realloc() 旧大小无效

问题描述 投票:0回答:6

我正在做 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无效的旧大小,但无法遵循将指针传递给修改数组的函数的指针的逻辑。

c dynamic-memory-allocation realloc
6个回答
13
投票

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

在您的情况下,问题是您在

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

尝试动态分配字符数组

line

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

6
投票

当您的代码写入

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

在您的情况下,传递给

realloc
的指针实际上是在自动内存中分配的数组 - 即它不是有效的指针。要修复此问题,请更改
line
longest
的声明,如下所示:

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

为了避免内存泄漏,请确保在程序末尾调用

free(line)
free(longest)


1
投票

您正在尝试

realloc()
未使用
malloc()
动态分配的内存。 你不能那样做。

此外,如果

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


1
投票

如果

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

此外,从

realloc()
分配的内存将在对
_getline()
的调用结束时泄漏。

此外,我们假设输入字符串是

"0123456789\n"
。然后,您将尝试写入
longest
该值,但在执行此操作之前,您将 never 调用
realloc()
,这是必需的。


0
投票

您的错误在这里:

int _getline(char s[])

这意味着

_getline
是一个返回
int
并按值获取指向
char
的指针的函数。

您实际上想通过引用传递该指针(该指针 必须指向用

malloc()
分配的内存或为
NULL
)。

这意味着,您需要将一个指针传递给指向

char
的指针。

纠正该错误将迫使您也纠正所有后续错误。

仅在

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


0
投票

我也遇到了同样的错误,我错误地使用了 malloc。

我有什么:

struct dataBlock *B = (struct dataBlock*) malloc(1 * sizeof(struct dataBlock*);
然后在
struct dataBlock *B

内分配数据

我需要什么:

struct dataBlock *B = (struct dataBlock*) malloc(1 * sizeof(struct dataBlock);

当我需要为

dataBlock*
分配空间时,我已经为指针
dataBlock
分配了空间;这会导致某些成员变量出现奇怪的值,并在尝试在
realloc() invalid old size
 内分配数据时导致错误 
dataBlock *B

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.