评论中的解决方案。
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
。
vertex
和 edge
都不包含指针字段,因此没有其他东西可以释放。您需要做的就是:
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/