c - 如何释放更复杂的嵌套结构

标签 c struct nested segmentation-fault free

评论中的解决方案。

typedef struct Vertex {
    int i;
    int color;
} vertex;

typedef struct Edge {
    vertex v1;
    vertex v2;
} edge;

typedef struct Node {
    void *p;
    struct Node *next;
} node;

基本上这是一个链表(节点)。 在我的程序中,我知道节点数组是否包含边或顶点。

我不确定如何正确释放边缘列表,我尝试了以下方法:

static void freeEdgeList(node *list) {
    if (list == NULL) return;
    node *ptr = list;
    node *tmp;
    do {
        tmp = ptr->next;
        free(&((*((edge *)(ptr->p))).v1));
        free(&((*((edge *)(ptr->p))).v2));
        free(ptr->p);
        free(ptr);
    } while ((ptr = tmp) != NULL);
}

因为我的结构 Edge 不存储指针,是否足以释放边缘结构而不释放存储在边缘中的顶点? 我有点困惑。

编辑:

static int addEdge(edge *e, node **list) {
    if ((*list) == NULL) {
        (*list) = malloc(sizeof(node));
        if ((*list) == NULL) return -1;
        (*list)->p = malloc(sizeof(edge));
        if ((*list)->p == NULL) return -1;
        memcpy(&((*list)->p), &e, sizeof(edge));
        (*list)->next = NULL;
    } else {
        node *tmp = (*list);
        while (tmp->next != NULL) {
            tmp = tmp->next;
        }
        tmp->next = malloc(sizeof(node));
        if (tmp->next == NULL) return -1;
        tmp = tmp->next;
        tmp->p = malloc(sizeof(edge));
        if (tmp->p == NULL) return -1;
        tmp->next = NULL;
        memcpy(&(tmp->p), &e, sizeof(edge));
    }
    return 0;
}

这是向列表添加边的函数(最初传入的列表为 NULL)。 它似乎正确地添加了边缘,因为我可以很好地将列表输出到控制台。 但是如果我尝试释放:

static void freeEdgeList(node *list) {
    while (list) {
        node *tmp = list;
        list = list->next;
        free(tmp->p);
        free(tmp);
    }
}

我收到不同的错误(段错误、无效指针)

最佳答案

您只能将 malloc 和 family 返回的内容准确传递给 free。由于您大概调用了 malloc 来分配一个 node,因此您只需要释放一个 node

vertexedge 都不包含指针字段,因此没有其他东西可以释放。您需要做的就是:

static void freeEdgeList(node *list) {
    while (list) {
        node *tmp = list;
        list = list->next;
        free(tmp->p);
        free(tmp);
    }
}

编辑:

在添加边的代码中,您错误地这样做了:

memcpy(&((*list)->p), &e, sizeof(edge));
...
memcpy(&(tmp->p), &e, sizeof(edge));

因为 e 是一个 edge *,它所做的就是将 指针值 e 复制到字段 p 而不是它指向的内容。这导致 p 指向的 edge 对象具有无效值。你反而想要:

memcpy((*list)->p, e, sizeof(edge));
...
memcpy(tmp->p, e, sizeof(edge));

这将复制 e 指向的 edge 中包含的值。

关于c - 如何释放更复杂的嵌套结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54150012/

相关文章:

c - 查找最大数字在数组中出现的次数

c - 用 C 语言制作问答游戏

matlab - 如何从结构中获取所有数据?

python - 如何在Python中将嵌套列表拆分为多个列表?

C 兴趣嵌套循环

c++ - vfork()../nptl/sysdeps/unix/sysv/linux/raise.c : No such file or directory

c - 移动钻石的下半部分

c - 在 LKM 中使用 ELF 部分

jsp - Struts <html :select> set selected option dynamically

javascript - 迭代 Meteor.js 中的嵌套对象并将结果插入表中