如何在调用strcpy之前分配数组?

时间:2010-09-12 14:55:53

标签: c string

假设:

char test[] = "bla-bla-bla";

两者中哪一个更正确?

char *test1 = malloc(strlen(test));
strcpy(test1, test);

char *test1 = malloc(sizeof(test));
strcpy(test1, test);

8 个答案:

答案 0 :(得分:24)

这将适用于所有以null结尾的字符串,包括指向char数组的指针:

char test[] = "bla-bla-bla";
char *test1 = malloc(strlen(test) + 1);
strcpy(test1, test);

char*const char*sizeof指向的数组的大小不正确。因此,该解决方案更加通用。

答案 1 :(得分:3)

既不:

#include <string.h>
char *mine = strdup(test);

答案 2 :(得分:3)

您应该使用strlen,因为如果您将test更改为运行时定义的字符串,sizeof将无提示失败。这意味着strlensizeof更安全,因为它会继续发挥作用。

答案 3 :(得分:2)

char test[]="bla-bla-bla";
char *test1 = malloc(strlen(test) + 1); // +1 for the extra NULL character
strcpy(test1, test);

答案 4 :(得分:2)

我认为sizeof是正确的。背后的原因是strlen(str)将给出字符串的长度(不包括终止空值)。如果您使用strcpy,它实际上会复制整个字符串,包括终止空值,因此如果您在strlen中使用malloc,则会减少一个字节。但sizeof给出了test指向的字符串的大小,包括终止null,因此您将获得正确大小的malloc块来复制包含终止空值的字符串。

答案 5 :(得分:1)

1)肯定会导致UB

2)可能导致UB(如果malloc失败)

我选择2)因为这个结构有更好的机会按预期工作;或者甚至更好我会在所有情况下编写一个按预期工作的版本(没有UB)。


修改

  • 1)中未定义的行为

    test1将为test中的字符留出空间,但不会为终止'\0'留出空间。对strcpy()的调用将尝试将'\0'写入不属于test1的内存,因此写入UB。

  • 2)中的未定义行为

    如果对malloc()的调用未能保留所请求的内存,则test1将被分配NULL。将NULL传递给strcpy()会调用UB。

应始终测试对malloc()(以及calloc()和朋友)的调用的返回值,以确保操作按预期工作。

答案 6 :(得分:0)

(1)strlen但不添加1肯定是不正确的。如果你加1,它会有额外的好处,它也适用于指针,而不仅仅是数组。

另一方面,只要你的字符串实际上是一个数组,(2)是首选,因为它导致编译时常量,而不是对strlen的调用(因此代码越来越快) )。实际上像gcc这样的现代编译器如果知道字符串是常量的话可能会优化strlen,但编译器可能很难确定它,所以我总是使用sizeof在可能的时候。

答案 7 :(得分:0)

如果它是关键路径,sizeof优于strlen,因为它具有O(1)复杂度,可以节省CPU周期。