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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3695263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:26:02  来源:igfitidea点击:

How to allocate the array before calling strcpy?

cstring

提问by LLL

Given:

鉴于:

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

Which of the two is more correct?

两者哪个更正确?

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

or

或者

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

回答by Tomasz Kowalczyk

This will work on all null-terminated strings, including pointers to chararrays:

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

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

You won't get the correct size of the array pointed to by char*or const char*with sizeof. This solution is therefore more versatile.

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

回答by Puppy

You should use strlen, because sizeofwill fail silently if you change test to be a run-time defined string. This means that strlenis a far safer idea than sizeofas it will keep working.

您应该使用strlen, 因为sizeof如果您将 test 更改为运行时定义的字符串,则会静默失败。这意味着这strlen是一个更安全的想法,sizeof因为它会继续工作。

回答by Matt Joiner

Neither:

两者都不:

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

回答by Anil Vishnoi

I think sizeofis the correct one. Reason behind that is strlen(str)will give you length of the string( excluding the terminating null). And if you are using strcpy, it actually copy the whole string including the terminating null, so you will allocate one byte less if you use strlenin malloc. But sizeofgives the size of the string pointed by test, including the terminating null, so you will get correct size mallocchunk to copy the string including the terminating null.

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

回答by mmonem

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

回答by pmg

1) definitely causes UB

1)肯定会导致UB

2) may cause UB (if mallocfails)

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

I'd go with 2) as there is a better chance of the construct working as intended; or even better I'd write a version that works as intended (without UB) in all situations.

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



Edit

编辑

  • Undefined Behaviour in 1)

    test1will have space for the characters in test, but not for the terminating '\0'. The call to strcpy()will try to write a '\0'to memory that does not belong to test1, hence UB.

  • Undefined Behaviour in 2)

    If the call to malloc()fails to reserve the requested memory, test1will be assigned NULL. Passing NULLto strcpy()invokes UB.

  • 1) 中的未定义行为

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

  • 2) 中的未定义行为

    如果 调用malloc()未能保留请求的内存,test1则将分配NULL。传递NULLstrcpy()调用 UB。

The return value of calls to malloc()(and calloc()and friends) should always be tested to ensure the operation worked as expected.

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

回答by R.. GitHub STOP HELPING ICE

(1) with strlenbut not adding 1 is definitely incorrect. If you add 1, it would have the added benefit that it also works for pointers, not just arrays.

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

On the other hand, (2) is preferred as long as your string is actually an array, as it results in a compile-time constant, rather than a call to strlen(and thus faster and smaller code). Actually a modern compiler like gcccan probably optimize the strlenout if it knows the string is constant, but it may be hard for the compiler to determine this, so I'd always use sizeofwhen possible.

另一方面,只要您的字符串实际上是一个数组,则首选 (2),因为它会导致编译时常量,而不是调用strlen(因此代码更快更小)。实际上,如果现代编译器知道字符串是常量,它可能gcc会优化strlen输出,但是编译器可能很难确定这一点,所以我总是sizeof尽可能使用。

回答by user3141529

If it is a critical path, sizeofhas advantage over strlenas it has an O(1) complexity which can save CPU cycles.

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