【问题标题】:Realloc Invalid Pointer. Aborted (core dumped)Realloc 无效指针。中止(核心转储)
【发布时间】: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 既然你给了我答案,那不是更好吗?

标签: c pointers realloc


【解决方案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 的建议!

      【讨论】:

        猜你喜欢
        • 2019-07-22
        • 2021-03-11
        • 2020-12-05
        • 1970-01-01
        • 2020-08-04
        • 1970-01-01
        • 2017-02-01
        • 2021-04-18
        • 1970-01-01
        相关资源
        最近更新 更多