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