在C结构上使用free
我有一个简单的链接列表节点如下
typedef struct node { void *data; struct ListElement *next; } node;
我还有一个节点创建和删除function,如下所示:
void createNode(void *data){ node *n = malloc(sizeof(node)); //assign data to data and initialize pointer to NULL } void deleteNode(List *list, Node *node){ //Take care of the next pointer free(node); }
当我释放节点时,是否还必须删除结构的成员(数据和下一个指针)? 既然我没有专门为成员使用malloc,而只是为了整个结构? 如果是的话那我该怎么做? 是否将节点的所有成员放在堆上,并且根本不会使用堆栈?
最终规则:你free()
与malloc()
(或calloc()
或…) 完全相同的次数
所以:
I.如果data
指向由这些function分配的内容,那么是的,您需要这样做。
II。 node->next
将被释放(假设你正在释放整个列表),所以无论如何你需要释放它, 但只有在你处理完下一个元素之后。
迭代解决方案:
void free_list(Node *list) { while (list != NULL) { Node *p = list->next; // maybe: // free(list->data); free(list); list = p; } }
递归解决方案:
void free_list(Node *list) { if (list->next != NULL) { free_list(list->next); } // free(list->data); free(list); }
通常,您还需要free
data
成员,并且必须在free
node
之前执行此操作,
free(node->data); free(node);
但你不需要free
node->next
,因为要么保留列表的其余部分,要么free
整个列表,然后释放下一个在循环的下一次迭代中完成。
如果不指向已分配(使用malloc
等)内存,则不得释放node->data
,但这种情况很少见。
data
不是变量,它是struct node
的成员。 如果通过调用malloc()
动态分配struct node
,则会得到足够大的内存块来容纳struct的所有成员。 这显然包括data
指针的存储,但不包括指针指向的内容 。 因此,结构成员的存储不能单独释放,这足以free
结构。
但是,由于data
本身就是一个指针,因此无法确定它指向的内存在哪里以及是否需要释放此内存,直到我们看到它是如何初始化的。