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的指针实际上是一个在自动内存中分配的数组 – 即它不是一个有效的指针。 要修复,请更改linelongest的声明,如下所示:

 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 。 从malloccallocrealloc或指定返回这样一个指针的函数返回的指针。