C语言中,当使用超过缓冲区大小的字符串时,需要使用空字符终止符。

3

注意:

这是关于纯C语言的问题。不涉及C++函数等。


问题:

假设我malloc了一个可以容纳100个char的缓冲区。然后,我只用实际的char填充其中5个插槽。我听说最佳实践是要将缓冲区中所有剩余的插槽都置空,像这样:

while (nextAvailableBufferSlot < currentBufferSize) 
{
    buffer[nextAvailableBufferSlot] = '\0';
    nextAvailableBufferSlot++;
}

这是必须的吗?还是我可以简单地设置buffer[5] = '\0'并省去循环呢?

上下文:

所涉及的代码经常使用大小为4096的缓冲区,而被复制到其中的99%字符串要短得多,这使得上面的循环几乎每次都要运行至少几千次。

我无法预先知道字符串的大小。由于重新分配非常昂贵,因此我最初选择了一个大的缓冲区大小。我针对桌面级硬件进行优化,因此内存不受限制。


这里不是很相关,但您真的是指"ANSI C",还是只是指"严格C",就像"把你们的C ++答案藏起来"?如果是后者,就像我想象的那样,标签就足够了。 - Ed S.
我从未听说过这样的最佳实践,我真的不会称之为最佳。即使你需要这样做(例如访问乱序字符),memset也是可行的方法。 - Gábor Buella
4个回答

1
如果您要复制字符串,可以使用strncpy来复制字符串,多余的缓冲区空间将自动用\0填充。
如果由于某种原因您正在使用strcpy或手动复制字符串,那么是的,您可以省略循环,因为所有标准字符串操作(strlenstrcpy等)都会在第一个\0处停止。

0

简短的回答是,你说得对。你真的只需要一个空指针,它位于数组中最后一个字符的右侧。

通常的答案是,为什么不使用char指针呢?类似字符串的char*可以为您处理整个头痛问题,并且有专门设计用于更轻松地操作这些内容的库。您不需要直接分配内存。您是否有特定的原因需要精确为100的缓冲区?


谢谢 - 这里的示例是为了简单起见而创造的。在我的实际项目中,缓冲区确实是 char*。我不仅仅是将字符串复制到它里面,而是在解析输入时逐个字符地构造一个字符串。 - Bryan
你说的“为什么不直接使用char指针?”是什么意思?他已经在使用char*,那就是malloc返回的。你是建议他使用字符串字面值吗?而你所说的“类似字符串的char*会为你处理所有麻烦”是什么意思?字符串管理是C语言中最让人头疼的方面之一,没有什么是可以“为你处理”的,除非你使用不能修改的字符串字面值。 - Ed S.
他的评论澄清了他想做什么。我以为他直接malloc一个100个字符的数组,而不是制作一个char*。不,我并不建议使用字符串字面值。 - Ryan Cori

0

实际上,你只需要在最后一个填充位置之后的第一个位置加上NUL终止符号。 这就是任何函数在操作字符串时知道何时停止所需的全部内容。


0

使用Calloc()函数代替。它会自动将内存块初始化为零(即相当于分配NULL,因为NULL的ASCII码为0)。然后您就不需要显式地将每个插槽分配给Null。


是的,我知道Calloc。但它在幕后做的事情是一样的,这使得它更慢。重点是速度,因为这段代码会被频繁使用。 - Bryan

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