N中的Null终止字符串

时间:2011-11-20 16:25:58

标签: c string null

我对C中的字符串非常焦虑。我是否需要设置最后一个字符\ 0或它是由它自己完成的?如果我不手动执行,那么当我尝试调试代码时,当我访问string1 [257]时,它不是空的。我遇到了释放字符串数组的已分配内存的问题所以我认为这是一个原因。

char string1[257], string2[257];
scanf("%s", &string2);
string1[257] = '\0';
strncpy(string1, string2, 257);
string1[257] = '\0'; /* do I need to do that? */

5 个答案:

答案 0 :(得分:1)

"Hello World!"之类的字符串文字以空值终止,但char数组不会自动以空值终止。

我一直采取的一般原则是要格外小心并将'\0'分配给字符串的末尾,除非这会导致性能问题。在这些情况下,我特别注意我使用的库函数。

答案 1 :(得分:1)

"foo\nbar"这样的文字字符串总是被转换为const char literal[],末尾有一个额外的零字节。 (因此常量将有8个字节,第一个为f,最后一个为零。)

但是你在strncpy之后明确强制将最后一个字节强制为0是正确的。

正如Aurelio De Rosa所说,对于数组[257],最后一个正确的索引是256。

答案 2 :(得分:1)

是的,你需要这样做。并非所有函数都为您设置null char,而strncpy,正如我在其手册页中所读到的那样,需要在src的前n个字符中包含空字节。

答案 3 :(得分:1)

绝对有必要吗? ,因为当您致电scanf时,strcpystrncpy除外,如果超过大小需要手动输入零),则复制空你的终结者。反正这样做好吗? 不是真的,它并没有真正帮助缓冲区溢出的问题,因为这些函数无论如何都将超过缓冲区的大小。那么最好的方法是什么?将c ++与std::string一起使用。

顺便说一句,如果您访问/写入string1[257],那么由于您正在访问/编写大小为257的数组中的 258th 元素,因此它将超出约束。(它是基于0的索引)

答案 4 :(得分:1)

要小心为字符串分配足够的内存,比较以下代码行的效果:

char s1[3] = "abc";
char s2[4] = "abc";
char s3[] = "abc";

这三个都被认为是合法的代码行(http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html),但在第一种情况下,第四个以空字符结尾的字符没有足够的内存。 s1的行为不像普通字符串,但s2和s3会。编译器自动计数s3,并获得四个字节的已分配内存。如果你试着写

s1[3] = '\0';

这是未定义的行为而你正在写入不属于s1的内存,并且会产生奇怪的效果,甚至可能会破坏malloc的后端信息,从而难以释放内存。