0

我有一个简单的链表节点如下

typedef struct node {
    void *data;
    struct ListElement *next;           
} node;

我还有一个节点创建和删除功能,如下所示:

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,而只为整个结构使用 malloc?如果是这样,那我该怎么做?会不会把节点的所有成员都放在堆上,栈就完全不用了?

4

3 回答 3

2

最终规则:你free()的次数完全相同malloc()(或calloc(),或...)

所以:

I. 如果data指向这些函数分配的东西,那么是的,你需要这样做。

二、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);
}
于 2013-04-27T18:02:11.793 回答
1

通常,您还需要free该成员,并且您必须在ingdata之前这样做,freenode

free(node->data);
free(node);

但你不需要free node->next,因为要么你想保留列表的其余部分,要么你想保留free整个列表,然后释放下一个是在循环的下一次迭代中完成的。

node->data如果这不指向分配的(使用或类似的)内存,则不能释放malloc,但这是一种罕见的情况。

于 2013-04-27T17:59:17.763 回答
1

data不是变量,它是 的成员struct node。如果你struct node通过调用动态分配malloc(),你会得到一块足够大的内存来容纳结构的所有成员。这显然包括data指针的存储,但不包括指针指向的内容。因此,结构成员的存储空间不能单独释放,free对结构来说就足够了。

然而,由于data它本身就是一个指针,所以在我们看到它是如何初始化的之前,不知道它指向的内存在哪里以及是否需要释放这块内存。

于 2013-04-27T18:11:14.390 回答