[英]Why does realloc fail on repeated calls where as allocating a big chunk using malloc works?
我正在尝试从标准输入中读取(从文件中传递值)。 我正在从字符串中读取每个字符,并将其存储到动态分配的字符串指针中。 需要时我重新分配内存。 我正在尝试获取尽可能多的字符。 虽然我可以将其限制为100,000个字符。 但是经过一些迭代后,重新分配失败。 但是,如果我在malloc的第一次初始化期间指定了较大的块大小(例如1048567),则可以完全读取该字符串。 为什么是这样?
下面是我的程序:
#include <stdio.h>
#include <stdlib.h>
int display_mem_alloc_error();
enum {
CHUNK_SIZE = 31 //31 fails. But 1048567 passes.
};
int display_mem_alloc_error() {
fprintf(stderr, "\nError allocating memory");
exit(1);
}
int main(int argc, char **argv) {
int numStr; //number of input strings
int curSize = CHUNK_SIZE; //currently allocated chunk size
int i = 0; //counter
int len = 0; //length of the current string
int c; //will contain a character
char *str = NULL; //will contain the input string
char *str_cp = NULL; //will point to str
char *str_tmp = NULL; //used for realloc
str = malloc(sizeof(*str) * CHUNK_SIZE);
if (str == NULL) {
display_mem_alloc_error();
}
str_cp = str; //store the reference to the allocated memory
scanf("%d\n", &numStr); //get the number of input strings
while (i != numStr) {
if (i >= 1) { //reset
str = str_cp;
len = 0;
curSize = CHUNK_SIZE;
}
c = getchar();
while (c != '\n' && c != '\r') {
*str = (char *) c;
//printf("\nlen: %d -> *str: %c", len, *str);
str = str + 1;
len = len + 1;
*str = '\0';
c = getchar();
if (curSize / len == 1) {
curSize = curSize + CHUNK_SIZE;
//printf("\nlen: %d", len);
printf("\n%d \n", curSize); //NB: If I comment this then the program simply exits. No message is displayed.
str_tmp = realloc(str_cp, sizeof(*str_cp) * curSize);
if (str_tmp == NULL) {
display_mem_alloc_error();
}
//printf("\nstr_tmp: %d", str_tmp);
//printf("\nstr: %d", str);
//printf("\nstr_cp: %d\n", str_cp);
str_cp = str_tmp;
str_tmp = NULL;
}
}
i = i + 1;
printf("\nlen: %d", len);
//printf("\nEntered string: %s\n", str_cp);
}
str = str_cp;
free(str_cp);
free(str);
str_cp = NULL;
str = NULL;
return 0;
}
谢谢。
当您重新realloc
str_tmp = realloc(str_cp, sizeof(*str_cp) * curSize);
if (str_tmp == NULL) {
display_mem_alloc_error();
}
//printf("\nstr_tmp: %d", str_tmp);
//printf("\nstr: %d", str);
//printf("\nstr_cp: %d\n", str_cp);
str_cp = str_tmp;
str_tmp = NULL;
您让str_cp
指向新的内存块,但是str
仍然指向旧的,现在free
d块。 因此,当您在下一次迭代中访问str
指向的内容时,您将调用未定义的行为。
您需要保存str
相对于str_cp
的偏移量,在重新分配之后,让str
指向新块的旧偏移量。
和*str = (char *) c;
这是错误的,尽管在功能上等同于正确的*str = c;
可能性不为零*str = c;
。
*str = (char *) c;
这行是错误的。
str
是指向char
的指针,而*str
是char
但是您正在将char
的指针分配给char
。 这无法在C中完成。
此外:
scanf("%d\n", &numStr);
scanf
调用中的\\n
可能不符合您的期望:
http://c-faq.com/stdio/scanfhang.html
并且:
str = str_cp;
free(str_cp);
free(str);
你在这里有双重自由。 赋值后, str
和str_cp
将具有相同的值,如下所示:
free(str_cp);
free(str);
就像您这样做:
free(str);
free(str);
这是未定义的行为(您不能释放两次)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.