我有以下C代码。我有两个指向同一个对象的指针。 它说双重自由错误。有人可以帮忙看看问题是什么吗?感谢。
#include <stdlib.h>
#include <stdio.h>
typedef struct edge {
int head;
} edge_t;
typedef struct edge_list_t {
edge_t *edge;
} edge_list_t;
int main() {
edge_list_t *p1;
edge_list_t *p2;
edge_t *c;
p1 = malloc(sizeof(edge_list_t));
p2 = malloc(sizeof(edge_list_t));
c = malloc(sizeof(edge_t));
p1->edge = c;
p2->edge = c;
free(c);
if (p2->edge) {
printf("not freed\n");
free(p2->edge);
} else {c
printf("freed\n");
}
return 1;
}
答案 0 :(得分:1)
p2->edge = c;
free(c);
if (p2->edge) {
printf("not freed\n");
free(p2->edge);
^最后free
是双free
。请注意,在第一次free
调用后,c
的值是无效值。
答案 1 :(得分:1)
下面:
p2->edge = c;
free(c);
当您空闲c
时,c
的值不会发生变化,即使它确实p2->edge
的值也会保持不变。它当然会保留c的原始值。
因此,您始终可以同时保留c
和p2->edge
,它们都具有相同的值。
如果您在其上调用c
并稍后检查free()
,则会将if(c)
设置为NULL,这将返回false而不是c
。
注意:free()不会以任何方式更改指针。它相信你指针指向正确的内存,而不是free()d。
答案 2 :(得分:0)
一旦您将对c
的控制权转移到p1
,您就不应该免费p1
,并且您不应让p2
和p1
共享一个边缘指针,你应该通过一个也释放边缘指针的函数释放p2
和#include <stdio.h>
#include <stdlib.h>
typedef struct edge
{
int head;
} edge_t;
typedef struct edge_list_t
{
edge_t *edge;
} edge_list_t;
// Will acquire a loop when you have an actual list of edges
static void free_edge_list(edge_list_t *e)
{
free(e->edge);
free(e);
}
int main(void)
{
edge_list_t *p1;
edge_list_t *p2;
edge_t *c;
p1 = malloc(sizeof(edge_list_t));
p2 = malloc(sizeof(edge_list_t));
c = malloc(sizeof(edge_t));
p1->edge = c;
c = malloc(sizeof(edge_t));
p2->edge = c;
free_edge_list(p1);
free_edge_list(p2);
return 0;
}
。这些观察结果导致:
{{1}}
通常,您应该检查内存分配是否成功;这段代码(仍然)没有这样做。