重新分配无效指针。中止(核心转储)

Realloc Invalid Pointer. Aborted (core dumped)

     *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()

发生错误,我正在使用一个临时元素*来阻止

观察:

使用 elemento* novo = malloc(sizeof(elemento*)); 时,您 malloc 仅 space 用于指针,但随后将其视为 space 用于结构。这会覆盖堆上的簿记信息。

类型 dado_t 是一个 char * 最初 没有指向任何东西(我的意思是,不是 NULL 而是一些随机值) .您在

中正确地为其分配了一些内存
novo->str = malloc(strlen(d) * sizeof(char));

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

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

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

然而,下一行是更严重的错误:

novo->str = d;

在 C 中,您不能 "assign" 一个字符串到另一个字符串。如果您想这样做,您可以将一个字符串的 地址 分配给另一个字符串。这可能会导致无法预料的问题,例如 'assigning' 地址是一个常量字符串(它是有效的但你不能修改它),或者更糟的是,一个在 'local' 上的函数内部创建的字符串堆叠.

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

strcpy (novo->str, d);

如果您释放结构 novo,请不要忘记此指针将为 "lost"。 "lost" 指针是您之前分配的内存块(在字符串 malloc 行中),但不再有指向的有效变量。因此,在释放 elemento 列表时,请先调用 free(xx->str)

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

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

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

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