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
虽然可能是NULL
; free
可以处理。实际上,您似乎总是分配一个值,所以这里不是这种情况,但总的来说,我发现明确清除新创建的结构是安全的,例如使用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() 时出现无效(中止)核心转储错误