评论中的解决方案。
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不存储指针,是否足以释放边缘结构而不释放存储在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);
}
}
我遇到了其他错误(段错误,指针无效)
答案 0 :(得分:2)
您只能将free
和家人返回的确切信息传递给malloc
。由于您大概调用了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
而不是其内容。指着。这导致edge
指向的p
对象具有无效值。相反,您想要:
memcpy((*list)->p, e, sizeof(edge));
...
memcpy(tmp->p, e, sizeof(edge));
这将复制edge
指向的e
中包含的值。
答案 1 :(得分:1)
规则是,如果您不分配它,那么您就不会释放它。如您所说,结构Edge
不包含任何动态内存分配或指针,因此您不会自己释放它们。内存分配为Edge
的一部分,并在释放时释放。
因此,请从free()
和v1
中删除v2
,仅使用free(ptr->p)
。
答案 2 :(得分:0)
是的,这是正确的。由于您不是malloc()
vertex
(它们不是指针,而是在Edge结构内部分配的变量),因此对于Edge结构,简单的free()
足够
答案 3 :(得分:0)
编辑:似乎我还不太明白。
感谢您的帮助,非常感谢!这对我来说很清楚。
while (list) {
node *tmp = list;
list = list->next;
free(&(tmp->p));
free(tmp);
}
此解决方案有效,我需要将指针的地址传递给free,而不是指针本身,我不太清楚为什么。
答案 4 :(得分:0)
正如其他人所提到的,freeEdgeList
需要修复[因此请遵循他们的回答]。
在addEdge
中,您的memcpy
呼叫不正确。您正在/从指针的地址复制数据,而不是指针指向的内容。
您要:memcpy((*list)->p, e, sizeof(edge))
和memcpy(tmp->p, e, sizeof(edge))
此外,在addEdge
中,如果*list == NULL
,则不要将其设置为第一个/新元素。
此外,代码可以简化一点。例如,在各处使用*list
有点麻烦。
这是经过修复的版本,其中修复了memcpy
和*list
的错误:
static int
addEdge(edge *e, node **list)
{
node *head = *list;
node *cur;
node *prev;
int ret = -1;
// find the end of the list
prev = NULL;
for (cur = head; cur != NULL; cur = cur->next)
prev = cur;
do {
// allocate new node
cur = malloc(sizeof(node));
if (cur == NULL)
break;
cur->next = NULL;
// add pointer to new edge
cur->p = malloc(sizeof(edge));
if (cur->p == NULL) {
free(cur);
break;
}
// copy in the edge data
memcpy(cur->p,e,sizeof(edge);
// link in new node
if (prev != NULL)
prev->next = cur;
else
head = cur;
// adjust list pointer
*list = head;
ret = 0;
} while (0);
return ret;
}