【发布时间】:2012-05-23 17:55:36
【问题描述】:
我正在试验 malloc 和 realloc 并想出了一些代码来解决以下问题:
我想创建一个未知大小的字符串,不设置任何限制。我可以问 用户获取 nr 个字符,但我宁愿将 str 调整为用户 键入每个字符。
所以我试图用 malloc + realloc 来做这件事,我的想法是每次用户输入一个新的字符时,我使用 realloc 请求 +1 块内存来保存字符。
在尝试实现这一点时,我犯了一个错误并最终执行了以下操作:
int main () {
/* this simulates the source of the chars... */
/* in reality I would do getch or getchar in the while loop below... */
char source[10];
int i, j;
for (i=0, j=65; i<10; i++, j++) {
source[i] = j;
}
/* relevant code starts here */
char *str = malloc(2 * sizeof(char)); /* space for 1 char + '\0' */
int current_size = 1;
i = 0;
while(i<10) {
char temp = source[i];
str[current_size-1] = temp;
str[current_size] = '\0';
current_size++;
printf("new str = '%s' | len = %d\n", str, strlen(str));
i++;
}
printf("\nstr final = %s\n", str);
return 0;
}
注意 realloc 部分还没有实现。
我编译并执行了这段代码,得到了以下输出
new str = 'A' | len = 1
new str = 'AB' | len = 2
new str = 'ABC' | len = 3
new str = 'ABCD' | len = 4
new str = 'ABCDE' | len = 5
new str = 'ABCDEF' | len = 6
new str = 'ABCDEFG' | len = 7
new str = 'ABCDEFGH' | len = 8
new str = 'ABCDEFGHI' | len = 9
new str = 'ABCDEFGHIJ' | len = 10
我发现这些结果很奇怪,因为我预计程序会崩溃:str 有 2 个字符的空间,并且代码在没有请求更多内存的情况下向 str 添加了超过 2 个字符。根据我的理解,这意味着我正在写在我不拥有的内存中,所以它应该给出一个运行时错误。
那么...为什么会这样?
(编译器为 GCC 4.3.4。)
提前致谢。
编辑: 其中一位评论者建议调用 free() 可能会导致发出错误信号。我尝试使用上面的代码调用 free() 并且执行代码没有导致错误。但是,在源数组中添加了更多的项,并且还调用了free,得到了以下错误:
* 检测到 glibc ./prog: free(): invalid next size (fast): 0x09d67008 **
【问题讨论】:
-
sizeof(char)是 1。你不需要拼出来。 -
顺便说一下,当实现这样的东西时,从一个相当大的缓冲区(比如,256 字节左右)开始通常是明智的,因为
malloc(1)对于大多数分配器来说效率不高。此外,通常值得避免过于频繁地调用realloc(),因此经常使用在每次重新分配时加倍 缓冲区大小的策略。当然,您的程序可能不会对性能至关重要,但我想指出这一点。