realloc()无效的旧大小

时间:2014-07-04 19:01:57

标签: c dynamic-memory-allocation realloc

我正在从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但是无法遵循将指针传递给指向修改数组的函数的指针的逻辑。

5 个答案:

答案 0 :(得分:9)

realloc调用将通过指向heap上的存储区域的指针重新分配内存,即调用malloc的动态分配内存结果。

在您的情况下,问题在于您在stack上分配内存,而不是通过调用malloc动态分配内存,从而导致heap上的内存分配。并且,将automatic字符数组line的指针传递给_getline,使用它来调用realloc。所以,你得到了错误。

尝试动态分配字符数组line

char* line  = (char *) malloc(MAXLINE); 
char* longest = ( char *) malloc(MAXLINE);

答案 1 :(得分:4)

当您的代码写入invalid old size / malloc为“内务信息”分配的内存时,会出现realloc错误。这是他们存储“旧”分配大小的地方。当您传递给realloc的指针未正确初始化时也会发生这种情况,即它既不是NULL也不是先前从malloc / calloc / {{返回的指针1}}。

在你的情况下,传递给realloc的指针实际上是一个在自动存储器中分配的数组 - 即它不是一个有效的指针。要解决此问题,请更改reallocline的声明,如下所示:

longest

为避免内存泄漏,请务必在程序结束时致电char *line = malloc(MAXLINE), *longest = malloc(MAXLINE); free(line)

答案 2 :(得分:1)

如果_getline()读取10个或更多字符,它将在未分配realloc()的内存上调用malloc()。这是未定义的行为

此外,从realloc()分配的内存将在_getline()的通话结束时泄露。

另外,我们假设输入字符串是"0123456789\n"。然后,您将尝试写入longest该值,但在执行此操作之前,永远不会调用realloc(),这是必需的。

答案 3 :(得分:1)

您正在尝试使用realloc()动态分配的malloc()内存。你不能这样做。

此外,如果realloc()失败,仍会分配原始内存,因此仍需要使用free()释放。所以不要将realloc()的返回值分配给原始指针,除非它不是NULL,否则你正在泄漏原始内存。首先将realloc()的返回值分配给临时变量,检查其值,然后仅在realloc()成功时才分配给原始指针。

答案 4 :(得分:0)

您的错误在这里:

int _getline(char s[])

这意味着_getline是一个函数,返回int按值获取指向char的指针。

您实际上想要通过引用传递该指针(必须指向使用malloc()分配的内存或NULL )。

这意味着,您需要将指针传递给指向char的指针。

纠正该错误也会强制您纠正所有后续错误。

仅在free上使用realloc / NULL。从malloccallocrealloc返回的指针或指定返回此类指针的函数。