使用'malloc'的'strcpy'函数?

17

像下面这样做是安全的吗?

#include <stdio.h>
#include <malloc.h>
#include <string.h>

int main(void)
{
    char* msg;

    strcpy(msg, "Hello World!!!");  //<---------

    printf("%s\n", msg);

    return 0;
}

还是应该使用以下方式?

char* msg = (char*)malloc(sizeof(char) * 15);

5
如果不使用malloc,msg指针将成为一个悬空指针。请使用malloc函数来分配内存空间。 - Paul R
3
使用 malloc,但不需要进行类型转换和使用 sizeof(char)。正确的用法是 char *msg = malloc(15); - R.. GitHub STOP HELPING ICE
另外,malloc() 的声明在 <stdlib.h> 中而不是 <malloc.h> 中。 - pmg
而且应该始终检查malloc()的返回值:char *msg = malloc(15); if (msg == NULL) /* 无法继续 */; - pmg
1
@MateuszPiotrowski:如果你不检查,就无法知道它是否“起作用”。返回NULL是malloc告诉你出了什么问题的方式。 - pmg
对于像我这样好奇的人,想知道为什么在这种情况下省略 sizeof(char) 是可以的(就像 @R..'s 评论中所说的那样):这个问题 解释了根据 C99 标准,sizeof(char)==1 - apnorton
6个回答

36

strdup为您执行malloc和strcpy操作。

char *msg = strdup("hello world");

2
strdup不是C标准,也不是C89和C99。 - user411313
13
POSIX是一种标准。我们使用的许多东西并不是C89或C99。这不是不使用如此简单的东西的理由。在编写像MYSTRDUP()这样密集的宏之前,请使用strdup。strdup只需要1行代码实现为函数,并且应该成为标准。 - codenheim
2
当然,但值得一提的是这是在POSIX中。 - Tor Klingberg
刚在 Win 10 上使用 strdup 函数时遇到了奇怪的问题,改用 malloc 和 strcpy 就可以正常工作了?! - colin lamarre
4
我会非常怀疑像“刚刚使用strdup时出现了奇怪的问题”这样的陈述。 - pm100
显示剩余2条评论

12

你的原始代码没有为msg分配内存。尝试使用strcpy将会有问题。在进行strcpy之前,你需要先为它分配一些空间。你可以像你所建议的那样使用malloc,或者在堆栈上分配空间,如下所示:

char msg[15];
如果您使用malloc分配内存,则应该记得在某个时候释放它。如果您在堆栈上分配内存,当其超出作用域(例如函数退出)时,内存将自动返回到堆栈。无论哪种情况,您都需要小心地分配足够的内存以便能够将最长的字符串复制到其中。您可能想看一下strncpy,以避免溢出数组。

如果msg的大小小于字符串的长度,比如"char msg[3]; strcpy(msg, "abcdefg");",这样可以吗?如果现在我cout msg,输出会是"abcdefg"吗? - Alcott
1
不会。char msg[3] 分配了三个字符的空间。你不能将8个字符复制到这个空间中(7个字母加上一个空终止符)。 - qbert220

2

使用:

#define MYSTRDUP(str,lit) strcpy(str = malloc(strlen(lit)+1), lit)

现在这很容易且符合标准:

char *s;
MYSTRDUP(s, "foo bar");

5
除非malloc失败,否则不可执行。 - pm100
缺少(char*)转换,#define MYSTRDUP(str,lit) strcpy(str = (char*)malloc(strlen(lit)+1), lit) - Eddinho

2
第一个版本不安全。而且,msg应该指向有效的内存位置,才能复制“Hello World!!!”。
char* msg = (char*)malloc(sizeof(char) * 15);
strcpy(msg, "Hello World!!!");

3
不要忽略malloc的返回值,也不要使用sizeof(char) - Jens Gustedt
4
为什么不用sizeof(char)? - pm100
1
在 C 语言中,char 类型被保证为 1 字节。 - yampelo
3
@yampelo,sizeof(char)既正确又清晰,但是有些冗余。不需要说“不要使用”。 - pm100

1
 char* msg;
 strcpy(msg, "Hello World!!!");  //<---------Ewwwww
 printf("%s\n", msg); 

这是UB。毫不犹豫。 msg 是一个野指针,尝试对其进行解引用可能会导致在您的实现中发生段错误。 msg 应指向足够大以容纳 "Hello World" 的有效内存位置。 尝试一下。
char* msg = malloc(15);
strcpy(msg, "Hello World!!!");

或者

char msg[20]; 
strcpy(msg, "Hello World!!!");

1
(UB == 未定义行为) - erik258

0
你需要分配空间。在使用 strcpy 之前使用 malloc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接