我正在尝试使用malloc和realloc,并为以下问题编写了一些代码:
我想创建一个未知大小的字符串,而不设置任何限制。我可以要求用户输入字符数,但我更愿意在用户输入每个字符时调整字符串大小。
因此,我尝试使用malloc + realloc来实现这个目标,我的想法是每次用户输入新字符时,我使用realloc请求+1个内存块以容纳该字符。
在尝试实现此过程时,我犯了一个错误,最终执行了以下操作:
请注意,realloc部分尚未实现。 我编译并执行了此代码,并得到以下输出。
我发现这些结果很奇怪,因为我预期程序会崩溃:str有2个字符的空间,但代码添加的字符数超过了2个,并没有请求更多的内存。据我的理解,这意味着我正在写入我不拥有的内存,所以应该会导致运行时错误。
那么... 为什么这个程序能够正常工作?
(编译器是GCC 4.3.4。)
提前感谢您的帮助。
编辑: 其中一位评论者建议调用free()可能会导致错误被标记。我尝试使用上述代码调用free(),执行代码时并没有出现错误。然而,在向源数组添加更多项并调用free后,出现了以下错误:
* glibc detected ./prog: free(): invalid next size (fast): 0x09d67008 **
我想创建一个未知大小的字符串,而不设置任何限制。我可以要求用户输入字符数,但我更愿意在用户输入每个字符时调整字符串大小。
因此,我尝试使用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个字符的空间,但代码添加的字符数超过了2个,并没有请求更多的内存。据我的理解,这意味着我正在写入我不拥有的内存,所以应该会导致运行时错误。
那么... 为什么这个程序能够正常工作?
(编译器是GCC 4.3.4。)
提前感谢您的帮助。
编辑: 其中一位评论者建议调用free()可能会导致错误被标记。我尝试使用上述代码调用free(),执行代码时并没有出现错误。然而,在向源数组添加更多项并调用free后,出现了以下错误:
* glibc detected ./prog: free(): invalid next size (fast): 0x09d67008 **
sizeof(char)
是 1。你不需要拼写出来。 - Kerrek SBmalloc(1)
的效率不是很高。此外,经常值得避免过于频繁地调用realloc()
,所以通常采用每次重新分配时将缓冲区大小*翻倍的策略。当然,你的程序可能不会受到性能的关键影响,但我想指出这一点。 - unwind