0

我有以下 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;
}
4

3 回答 3

1
p2->edge = c;

free(c);

if (p2->edge) {
    printf("not freed\n");
    free(p2->edge);

^ 最后一个free是 double free。请记住,在第一次free调用之后, 的值c是无效值。

于 2013-06-27T22:27:45.713 回答
1

这里:

p2->edge = c;

free(c);

当你释放时c,值c不会改变,即使它改变了,值p2->edge也会保持不变。它当然会保留 c 的原始值。所以你总是释放两者c,并且p2->edge两者都持有相同的价值。

为避免c在您调用free()它并稍后检查时将其设置为 NULL if(c),这将返回 false 并且不再空闲c

注意:free() 不会以任何方式更改指针。它相信你的指针指向正确的内存,之前从未 free()d。

于 2013-06-27T22:28:33.007 回答
0

c一旦你将控制权转移到,你就不应该释放它p1,你不应该同时拥有p1p2共享一个边缘指针,你应该释放p1p2通过一个也释放边缘指针的函数。这些观察导致:

#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;
}

一般来说,您应该检查内存分配是否成功;这段代码(仍然)没有这样做。

于 2013-06-27T22:47:39.377 回答