Realloc无效指针。中止(堆芯转储)

Realloc无效指针。中止(堆芯转储),c,pointers,realloc,C,Pointers,Realloc,为什么我会犯这个错误?因为myel->str是分配给malloc()的指针。为什么会出错?我正在使用一个临时元素*以防止realloc()发生错误 Obs:带有elemento*novo=malloc(sizeof(elemento*))只为指针分配空间,然后将其视为结构的空间。覆盖堆上的簿记信息。elemento*novo=malloc(sizeof(elemento*)只为指针分配空间,然后将其视为结构的空间。这会覆盖堆上的簿记信息。类型dado\t是一个char*,它最初指向nothing

为什么我会犯这个错误?因为
myel->str
是分配给
malloc()
的指针。为什么会出错?我正在使用一个临时元素*以防止realloc()发生错误


Obs:

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

类型
dado\t
是一个
char*
,它最初指向nothing(我的意思是,不是
NULL
,而是一些随机值)。在中为它正确分配了一些内存

     *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;
}
这有一个小错误:长度为
d
的C字符串需要多出一个字节的内存来终止零。所以把这个改成

novo->str = malloc(strlen(d) * sizeof(char));
这里有两个注意事项:
sizeof(char)
保证为
1
(我认为它在规范中;然后,它也没有坏处,也许您希望确保在分配
int
s或其他更大的类型时语法正确)。
第二,大多数标准库都有一个函数,它可以实现以下功能:。你所需要做的就是用你的字符串地址调用它,它本身就做+1部分

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

novo->str = malloc(strlen(d)+1);
在C语言中,不能用这种方式将一个字符串“赋值”给另一个字符串。如果要这样做,可以将一个字符串的地址分配给另一个字符串。这可能会导致不可预见的问题,例如为地址“分配”一个常量字符串(该字符串有效,但您无法修改),或者更糟糕的是,在“本地”堆栈上的函数内创建的字符串

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

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


如果在创建新的
elemento
结构时确保
str
元素始终设置为
NULL
,则可以安全地为字符串调用
free
,即使它可能是
NULL
<代码>免费
可以处理这个问题。事实上,您似乎总是分配一个值,所以这里不是这样,但一般来说,我发现明确清除新创建的结构是安全的,例如使用
memset(novo,0,sizeof(elemento))

类型
dado\t
是一个
char*
,它最初指向nothing(我的意思是,不是
NULL
,而是一些随机值)。在中为它正确分配了一些内存

     *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;
}
这有一个小错误:长度为
d
的C字符串需要多出一个字节的内存来终止零。所以把这个改成

novo->str = malloc(strlen(d) * sizeof(char));
这里有两个注意事项:
sizeof(char)
保证为
1
(我认为它在规范中;然后,它也没有坏处,也许您希望确保在分配
int
s或其他更大的类型时语法正确)。
第二,大多数标准库都有一个函数,它可以实现以下功能:。你所需要做的就是用你的字符串地址调用它,它本身就做+1部分

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

novo->str = malloc(strlen(d)+1);
在C语言中,不能用这种方式将一个字符串“赋值”给另一个字符串。如果要这样做,可以将一个字符串的地址分配给另一个字符串。这可能会导致不可预见的问题,例如为地址“分配”一个常量字符串(该字符串有效,但您无法修改),或者更糟糕的是,在“本地”堆栈上的函数内创建的字符串

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

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


如果在创建新的
elemento
结构时确保
str
元素始终设置为
NULL
,则可以安全地为字符串调用
free
,即使它可能是
NULL
<代码>免费
可以处理这个问题。事实上,您似乎总是分配一个值,所以这里不是这样,但一般来说,我发现明确清除新创建的结构是安全的,例如使用
memset(novo,0,sizeof(elemento))
Peter Schneider正确地指出,
elemento*novo=malloc(sizeof(elemento*))
只为指针分配了足够的空间(因为这就是
elemento*
的含义);在这种情况下,有两种常见的习语,其中一种在这里很好:

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

当然,你也需要接受Jongware的建议

彼得·施耐德正确地指出,
elemento*novo=malloc(sizeof(elemento*))
只为指针分配了足够的空间(因为这就是
elemento*
);在这种情况下,有两种常见的习语,其中一种在这里很好:

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

当然,你也需要接受Jongware的建议

您已经设置了
myel->str