Realloc 无效指针。中止(核心转储)

Posted

技术标签:

【中文标题】Realloc 无效指针。中止(核心转储)【英文标题】:Realloc Invalid Pointer. Aborted (core dumped) 【发布时间】:2015-05-04 23:35:32 【问题描述】:
     *MyFile.h*

        typedef char* dado_t;
        typedef struct elemento elemento;
        typedef struct lista2 lista2;  

    *MyFile.c*

    struct elemento
        dado_t str;
        elemento* ant;
        elemento* prox;
    ;

    struct lista2
        elemento* primeiro;
        elemento* ultimo;
        elemento* corrente;
    ;

    void_insert(lista2* l, dado_t d)
       elemento* novo = malloc(sizeof(elemento*));
       novo->str = malloc(strlen(d) * sizeof(char));
       novo->str = d;
       l->corrente = novo;
       l->primeiro = novo;
       l->ultimo = novo;
       novo->prox = NULL;
       novo->ant = NULL;

    

dado_t replace(lista2* l, dado_t d)
   dado_t retorno = malloc(strlen(corrente->str) * sizeof(dado_t));
   retorno = corrente->str;

   corrente->str = realloc(corrente->str, strlen(d) * sizeof(char));
   l->corrente->str = d;
   return retorno;

为什么会出现这个错误?因为myel->str 是一个已分配malloc() 的指针。为什么错误?如果 realloc()

发生错误,我正在使用临时元素*

观察:

【问题讨论】:

你在 malloc 之后将myel->str 设置为 d @Dinesh 是的,但是错误发生在编译器到达那里之前... =s 您是否想分享更多代码,因为调用顺序不清楚。也许 - 在 realloc 之前 - 只需打印 myel->str 和 d - 可能会提供一些线索 您不能将字符串分配给myel->str,您必须使用strcpy。 (并为您的strlen 行中的零终止符保留空间!) @Jongware 既然你给了我答案,那不是更好吗? 【参考方案1】:

使用elemento* novo = malloc(sizeof(elemento*));,您只为指针分配空间,然后将其视为结构的空间。这会覆盖堆上的簿记信息。

【讨论】:

【参考方案2】:

dado_t 类型是一个char *最初指向什么都没有(我的意思是,不是NULL,而是一些随机值)。您正确地为它分配了一些内存

novo->str = malloc(strlen(d) * sizeof(char));

其中有一个小错误:长度为 d 的 C 字符串需要多一个字节的内存用于终止零。所以把它改成

novo->str = malloc(strlen(d)+1);

这里有两个注意事项:sizeof(char) 保证是 1(我认为它在规范中;再说一遍,它没有害处,也许您想确保在分配 int 时使用正确的语法s 或其他更大的类型)。 其次,大多数标准库都有一个功能可以做到这一点:strdup。您需要做的就是用您的字符串地址调用它,它会自己完成 +1 部分。

但是,下一行是一个更严重的错误:

novo->str = d;

在 C 中,您不能以这种方式将一个字符串“分配”给另一个字符串。如果您想这样做,您可以将一个字符串的 地址 分配给另一个字符串。这可能会导致无法预料的问题,例如为地址“分配”一个常量字符串(这是有效的,但您不能修改它),或者更糟糕的是,一个在“本地”堆栈上的函数内部创建的字符串。

在这种情况下,您想要存储函数参数中字符串d 的完整副本,因此您可以使用

strcpy (novo->str, d);

不要忘记,如果你释放了结构novo,这个指针将会“丢失”。 “丢失”指针是您之前分配的一块内存(在字符串malloc 行中),但不再具有指向的有效变量。因此,在释放您的 elemento 列表时,请先致电 free(xx->str)

如果您确保在创建新的elemento 结构后立即将str 元素始终设置为NULL,您甚至可以安全地为字符串调用free虽然可能是NULLfree 可以处理。实际上,您似乎总是分配一个值,所以这里不是这种情况,但总的来说,我发现明确清除新创建的结构是安全的,例如使用memset (novo, 0, sizeof(elemento));

【讨论】:

【参考方案3】:

Peter Schneider 正确地指出 elemento* novo = malloc(sizeof(elemento*)) 只为指针分配了足够的空间(因为这就是 elemento* 的含义);在这种情况下,有两个常见的成语,在这里都可以:

elemento* novo = malloc(sizeof(elemento)) elemento* novo = malloc(sizeof(*novo))

当然你也需要听取 Jongware 的建议!

【讨论】:

以上是关于Realloc 无效指针。中止(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中使用 free() 时出现无效(中止)核心转储错误

防止核心转储使用空指针初始化字符串

realloc 使用详解(分析realloc invalid pointer指针无效等错误)

Mongodb 停止工作:中止(核心转储)

在递归合并排序期间中止(核心转储)

Python 服务器“中止(核心转储)”