我是一名相对新手的C程序员。我正在为一个练习C语言的项目编写教程,现在正在审查以下代码。 abuf
结构体的目的是创建一个可以追加的字符串。以下是代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct abuf {
char* str;
unsigned int size;
} abuf;
void abAppend(abuf *ab, const char *s, int len) {
char *new = realloc(ab->str, ab->size + len);
if (new == NULL) return;
memcpy(&new[ab->size], s, len);
ab->str = new;
ab->size += len;
}
int main(void) {
abuf ab = {
NULL,
0
};
char *s = "Hello";
abAppend(&ab, s, 5);
abAppend(&ab, ", world", 7);
return 0;
}
一切都编译通过了,我的测试(为简单起见已删除)显示字符串“Hello”存储在ab的str
指针中,然后在第二次调用abAppend
后变成“Hello, world”。但是,这段代码中的某些内容让我感到困惑。在对abAppend
进行初始调用时,str
指针为空,因此根据其手册,realloc
应该像malloc
一样分配5个字节的空间来存储字符串。但是,字符串“Hello”还包含终止的空字节\0。如果我理解正确,这应该是字符串的第六个和最后一个字节。如果我们将“Hello\0”存储在只足以存储“Hello”的malloc
容器中,那么这个空字节不就丢失了吗?
abAppend
时,我们将", world"连接到str
。 realloc
将扩大str
到12个字节,但第13个字节\0没有计算在内。然而,一切都正常运行,如果我使用像for (int i = 0; ab.str[i] != '\0'; i++)
这样的循环测试空字节,循环可以正常工作并增加i
12次(0到11),并停止,这意味着它在第13次迭代时遇到了空字节。我不明白的是,如果我们没有为其分配空间,为什么会遇到空字节。
我尝试通过奇怪的字符串组合来破坏此代码,但无济于事。我还尝试在每次调用abAppend
时分配一个额外的字节,并稍微更改函数以考虑额外的空间,结果与此版本完全相同。我不明白空字节是如何被处理的。
+1
。 - tadmanrealloc
会复制原始内存内容(但不会初始化额外的内存),malloc
和realloc
都不会初始化分配的内存。 - Weather Vanemalloc()
和realloc()
对字符串一无所知,它们只分配请求的内存量,可以用于任何类型的数据。你需要自己考虑空字节的问题。 - Barmar