realloc() 无效的旧大小
Posted
技术标签:
【中文标题】realloc() 无效的旧大小【英文标题】:realloc() invalid old size 【发布时间】:2014-08-26 02:41:08 【问题描述】:我正在从 KandR C 编程书中做一个有趣的练习。该程序用于从用户输入的一组行中找到最长的行,然后将其打印出来。
这是我写的(部分是直接从书中摘录的):-
#include <stdio.h>
#include <stdlib.h>
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 invalid old size,但无法遵循将指针传递给指向修改数组的函数的指针的逻辑。
【问题讨论】:
程序中的其他错误(使用括号确保计算和其他地方的含义)程序正在将 'int' 大小值写入 's' 数组,但仅分配 char 大小增量。跨度> 函数名'_getline'会与C库函数名冲突。而是使用类似“myGetLine”的东西 传递给 _getline 的参数不是指向 malloc 区域的指针,而是堆栈上区域的第一个地址。因此,尝试重新分配()该指针是错误的。建议获取 _getline 参数的初始指针为“line = (MAXSIZE*sizeof(int));” 执行realloc时,使用第二个参数((MAXLINE + INCREMENT)*sizeof(int)) 【参考方案1】:realloc
调用将通过获取指向heap
上存储区域的指针来重新分配内存,即调用malloc
的动态分配内存结果。
在您的情况下,问题是您在stack
上分配内存,而不是通过调用malloc
动态分配内存,从而导致heap
上的内存分配。并且,将automatic
字符数组line
的指针传递给_getline
,后者使用它来调用realloc
。所以,你得到了错误。
尝试动态分配字符数组line
:
char* line = (char *) malloc(MAXLINE);
char* longest = ( char *) malloc(MAXLINE);
【讨论】:
那么我的 _getline 函数将类似于 _getline(char* s)? @Karan,不要保持_getline
原样,在C
数组中names
自动decayed
指向指向它们的第一个元素的指针。
@Karan,请参阅***.com/questions/1461432/what-is-array-decaying 了解数组衰减。
谢谢。但是,在大输入时,我得到另一个与 realloc 相关的错误:*** `./a.out' 中的错误:realloc():下一个大小无效:0x00000000009ce010 *** 分段错误(核心转储)
@Karan,分段错误在 C 中很常见,并且在您分配的大小小于输入的大小时发生。在问题上下文中,您在堆上分配的内存较少,并尝试从您输入的大缓冲区数据中覆盖内存,因此您收到错误。有关更多信息,请参阅en.wikipedia.org/wiki/Segmentation_fault。【参考方案2】:
如果_getline()
读取了 10 个或更多字符,它将在未使用malloc()
分配的内存上调用realloc()
。这是未定义的行为。
此外,从realloc()
分配的内存将在对_getline()
的调用结束时泄漏。
此外,假设输入字符串是"0123456789\n"
。然后,您将尝试将该值写入longest
,但您将从不在此之前调用realloc()
,这是必需的。
【讨论】:
【参考方案3】:你的错误在这里:
int _getline(char s[])
这意味着_getline
是一个返回int
的函数,通过值获取指向char
的指针。
您实际上希望通过引用传递该指针(该指针必须指向使用malloc()
分配的内存或NULL
)。
也就是说,你需要传递一个指向char
的指针。
纠正该错误将迫使您也纠正所有后续错误。
仅在 NULL
上分别使用 free
/ realloc
。在从malloc
、calloc
、realloc
返回的指针或指定返回此类指针的函数上。
【讨论】:
【参考方案4】:当您的代码写入 malloc
/realloc
为“管家信息”分配的内存时,您会收到 invalid old size
错误。这是他们存储“旧”分配大小的地方。当您传递给 realloc
的指针未正确初始化时也会发生这种情况,即它既不是 NULL
也不是以前从 malloc
/calloc
/realloc
返回的指针。
在您的情况下,传递给 realloc
的指针实际上是一个分配在自动内存中的数组 - 即它不是一个有效的指针。要解决此问题,请将line
和longest
的声明更改如下:
char *line = malloc(MAXLINE), *longest = malloc(MAXLINE);
为避免内存泄漏,请确保在程序结束时调用 free(line)
和 free(longest)
。
【讨论】:
【参考方案5】:您正在尝试realloc()
未使用malloc()
动态分配的内存。你不能那样做。
另外,如果realloc()
失败,原始内存仍被分配,因此仍需要使用free()
释放。所以不要将realloc()
的返回值赋给原始指针,除非它不为NULL,否则就是在泄漏原始内存。将realloc()
的返回值先赋值给一个临时变量,检查它的值,只有realloc()
成功后才赋值给原来的指针。
【讨论】:
以上是关于realloc() 无效的旧大小的主要内容,如果未能解决你的问题,请参考以下文章