简体   繁体   English

C中的空终止字符串

[英]Null terminated string in C

I am quite anxious about strings in C. Do I need to set the last char \\0 or it does it by it self?我很担心 C 中的字符串。我需要设置最后一个字符 \\0 还是它自己设置? If I don't do it manually then when I try to debug code and when I access string1[257] it is not null.如果我不手动执行,那么当我尝试调试代码以及​​访问 string1[257] 时它不为空。 I am having problems with freeing allocated memory of an array of strings so I thought it was a reason.我在释放字符串数组的分配内存时遇到问题,所以我认为这是一个原因。

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

String literals like "Hello World!"字符串文字,如"Hello World!" are null-terminated, but char arrays are not automatically null terminated.以 null 结尾,但char数组不会自动以 null 结尾。

The general principle I've always taken is to be extra cautious and assign '\\0' to the the end of the string unless that causes a performance problem.我一直采取的一般原则是格外小心,将'\\0'分配到字符串的末尾,除非这会导致性能问题。 In those cases, I'm extra careful about which library functions I use.在这些情况下,我会格外小心我使用哪些库函数。

A literal string like "foo\\nbar" is always translated to a const char literal[] with an additional zero byte at the end."foo\\nbar"这样的文字字符串总是被转换为const char literal[]在末尾带有一个额外的零字节。 (So the constant would have 8 bytes, the first being f and the last being zero). (因此常量将有 8 个字节,第一个是f ,最后一个是零)。

But you are right in forcing explicitly the last byte to 0 after a strncpy .但是您在strncpy之后明确地将最后一个字节强制为 0 是正确的。

And as Aurelio De Rosa remarked, the last correct index is 256 for an array [257] .正如 Aurelio De Rosa 所说,数组[257]的最后一个正确索引是 256。

Yes, you need to do that.是的,你需要这样做。 Not all functions put the null char for you, and strncpy , as I can read in its man page, requires to have a null byte among the first n characters of src.并非所有函数都为您放置空字符,并且strncpy ,正如我在其手册页中所读到的那样,需要在 src 的前 n 个字符中包含一个空字节。

Is it absolutely necessary?绝对有必要吗? No , because when you call scanf , strcpy (except for strncpy where you need to manually put zero if it exceeds the size), it copies the null terminator for you.,因为当您调用scanfstrcpystrncpy除外,如果超出大小则需要手动置零),它会为您复制空终止符。 Is it good to do it anyways?无论如何这样做好吗? Not really , it doesn't really help the problem of bufferoverflow since those function will go over the size of the buffer anyways.不是真的,它并没有真正帮助解决缓冲区溢出问题,因为这些函数无论如何都会超过缓冲区的大小。 Then what's the best way?那么最好的方法是什么? use c++ with std::string .将 c++ 与std::string

By the way, if you access/write to string1[257] , that will be out of bound since you're accessing/writing 258th element in an array of size 257. (it's 0-based index)顺便说一句,如果您访问/写入string1[257] ,那将超出范围,因为您正在访问/写入大小为 257 的数组中的第 258 个元素。(它是基于 0 的索引)

Always be careful to allocate enough memory with strings, compare the effects of the following lines of code:始终小心为字符串分配足够的内存,比较以下代码行的效果:

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

All three are considered legal lines of code ( http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html ), but in the first case, there isn't enough memory for the fourth null-terminated character.这三个都被认为是合法的代码行( http://c-faq.com/ansi/nonstrings.htmlhttp://c-faq.com/ansi/nonstrings.html ),但在第一种情况下,没有足够的内存用于第四个空终止字符。 s1 will not behave like a normal string, but s2 and s3 will. s1 的行为不会像普通字符串,但 s2 和 s3 会。 The compiler automatically count for s3, and you get four bytes of allocated memory.编译器自动对 s3 进行计数,您将获得 4 个字节的分配内存。 If you try to write如果你尝试写

s1[3] = '\0';

that's undefined behavior and you're writing to memory that doesn't belong to s1, and would have weird effects, maybe even disrupting malloc's backend information, making it hard to free memory.这是未定义的行为,您正在写入不属于 s1 的内存,并且会产生奇怪的效果,甚至可能会破坏 malloc 的后端信息,从而难以释放内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM