realloc()无效的旧大小
我正在从KandR C编程书中做一些有趣的练习。 该程序用于从用户输入的一组行中查找最长行,然后打印它。
这是我写的(部分,部分内容直接取自本书): –
#include #include int MAXLINE = 10; int INCREMENT = 10; void copy(char longest[], char line[]){ int i=0; while((longest[i] = line[i]) != '\0'){ ++i; } } int _getline(char s[]){ int i,c; for(i=0; ((c=getchar())!=EOF && c!='\n'); i++){ if(i == MAXLINE - 1){ s = (char*)realloc(s,MAXLINE + INCREMENT); if(s == NULL){ printf("%s","Unable to allocate memory"); // goto ADDNULL; exit(1); } MAXLINE = MAXLINE + INCREMENT; } s[i] = c; } if(c == '\n'){ s[i] = c; ++i; } ADDNULL: s[i]= '\0'; return i; } int main(){ int max=0, len; char line[MAXLINE], longest[MAXLINE]; while((len = _getline(line)) > 0){ printf("%d", MAXLINE); if(len > max){ max = len; copy(longest, line); } } if(max>0){ printf("%s",longest); } return 0; }
当我在一行中输入超过10个字符时,程序崩溃并显示: –
*** Error in `./a.out': realloc(): invalid old size: 0x00007fff26502ed0 *** ======= Backtrace: ========= /lib64/libc.so.6[0x3d6a07bbe7] /lib64/libc.so.6[0x3d6a07f177] /lib64/libc.so.6(realloc+0xd2)[0x3d6a0805a2] ./a.out[0x400697] ./a.out[0x40083c] /lib64/libc.so.6(__libc_start_main+0xf5)[0x3d6a021b45] ./a.out[0x400549]
我还检查了realloc无效的旧大小,但无法遵循将指针传递给指向修改数组的函数的指针的逻辑。
realloc
调用将通过获取指向heap
存储区域的指针来重新分配内存,即调用malloc
的动态分配的内存结果。
在您的情况下,问题是您在stack
上分配内存而不是动态调用malloc
,这会导致heap
内存分配。 并且,将automatic
字符数组line
的指针传递给_getline
,后者使用它来调用realloc
。 所以,你得到了错误。
尝试动态分配字符数组line
:
char* line = (char *) malloc(MAXLINE); char* longest = ( char *) malloc(MAXLINE);
当您的代码写入malloc
/ realloc
为“内务处理信息”分配的内存时,会出现invalid old size
错误。 这是他们存储“旧”分配大小的地方。 当你传递给realloc
的指针没有被正确初始化时,也会发生这种情况,即它既不是NULL
也不是之前从malloc
/ calloc
/ realloc
返回的指针。
在你的情况下,传递给realloc
的指针实际上是一个在自动内存中分配的数组 – 即它不是一个有效的指针。 要修复,请更改line
和longest
的声明,如下所示:
char *line = malloc(MAXLINE), *longest = malloc(MAXLINE);
为避免内存泄漏,请确保在程序结束时调用free(line)
和free(longest)
。
您正在尝试使用malloc()
动态分配的realloc()
内存。 你不能这样做。
此外,如果realloc()
失败,仍然会分配原始内存,因此仍需要使用free()
释放。 所以不要将realloc()
的返回值赋给原始指针,除非它不是NULL,否则你正在泄漏原始内存。 首先将realloc()
的返回值分配给临时变量,检查其值,然后仅在realloc()
成功时分配给原始指针。
如果_getline()
读取10个或更多字符,它将在未使用malloc()
分配的内存上调用realloc()
malloc()
。 这是未定义的行为 。
此外,从realloc()
分配的内存将在对_getline()
的调用结束时泄露。
另外,我们假设输入字符串是"0123456789\n"
。 然后你会尝试写入longest
那个值,但是在你这样做之前你永远不会调用realloc()
,这是必需的。
你的错误在这里:
int _getline(char s[])
这意味着_getline
是一个返回int
的函数,它通过值获取指向char
的指针。
实际上,您希望通过引用传递该指针( 必须指向使用malloc()
分配的malloc()
或为NULL
)。
这意味着,您需要将指针传递给指向char
的指针。
更正该错误将迫使您纠正所有后续错误。
只在NULL
上使用free
/ realloc
。 从malloc
, calloc
, realloc
或指定返回这样一个指针的函数返回的指针。