在C结构上使用free

在C结构上使用free,c,malloc,C,Malloc,我有一个简单的链表节点,如下所示 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 }

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

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?如果是这样,我该怎么做?节点的所有成员都将被放置在堆上,而堆栈将根本不被使用吗

通常,您还需要
释放
数据
成员,并且您必须在
释放
节点
之前这样做

free(node->data);
free(node);
但是您不需要
释放
节点->下一个
,因为您想要保留列表的其余部分,或者
释放整个列表,然后在循环的下一次迭代中释放下一个


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

通常,您还需要
释放
data
成员,并且必须在
释放
node
之前执行此操作

free(node->data);
free(node);
但是您不需要
释放
节点->下一个
,因为您想要保留列表的其余部分,或者
释放整个列表,然后在循环的下一次迭代中释放下一个


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

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

因此:

I.如果
数据
指向这些函数分配的某些内容,则是,您需要这样做

二,<代码>节点->下一个
当然会被释放(假设你正在释放整个列表),所以你无论如何都需要释放它,但只有在你处理好下一个元素之后。

迭代解决方案:

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);
}
递归解决方案:

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()
的次数与你
malloc()
的次数完全相同(或
calloc()
,或…)

因此:

I.如果
数据
指向这些函数分配的某些内容,则是,您需要这样做

二,<代码>节点->下一个
当然会被释放(假设你正在释放整个列表),所以你无论如何都需要释放它,但只有在你处理好下一个元素之后。

迭代解决方案:

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);
}
递归解决方案:

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);
}

数据
不是变量,它是
结构节点
的成员。如果通过调用
malloc()
动态分配
struct节点
,则会得到足够大的内存块来容纳结构的所有成员。这显然包括
数据
指针的存储,但不包括指针指向的内容。因此,不能单独释放结构成员的存储,只需
释放该结构即可


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

data
不是一个变量,它是
结构节点的成员。如果通过调用
malloc()
动态分配
struct节点
,则会得到足够大的内存块来容纳结构的所有成员。这显然包括
数据
指针的存储,但不包括指针指向的内容。因此,不能单独释放结构成员的存储,只需
释放该结构即可


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

基本上每个
malloc()
都应该有一个相应的
free()
。我不是专门使用malloc来分配数据变量的。那么它被放在堆栈上了吗?数据位于哪里并不重要。如果它不是通过
malloc()
获得的,您就不会
free()
它。它可以在堆栈上、寄存器上、交换磁盘上,
struct node
有一个
next
成员,该成员不是指向另一个
struct node
,而是指向一个
struct listement
(您还没有向我们展示)。这似乎很奇怪。谢谢你的解释!基本上,每个
malloc()
都应该有一个相应的
free()
。我并不是专门使用malloc来分配数据变量。那么它被放在堆栈上了吗?数据位于哪里并不重要。如果它不是通过
malloc()
获得的,您就不会
free()
它。它可以在堆栈上、寄存器上、交换磁盘上,
struct node
有一个
next
成员,该成员不是指向另一个
struct node
,而是指向一个
struct listement
(您还没有向我们展示)。这似乎很奇怪。谢谢你的解释!啊,我明白了。在我的例子中,数据指向堆栈上的某个对象,因此我不需要释放它。你的意思是:但是只有在你处理了下一个元素之后,对吗?谢谢你的回答。因此指针本身存储在结构中。所以当我释放一个节点时,指针变量也被释放,对吗?@rgamber是的,把一个结构看作一块内存。如果你释放它,里面的一切都会被释放。不管它是否是指针。如果是指向动态分配内存的指针,则必须通过或使用该指针释放该内存,但请记住:
free()
对指针itsef没有任何作用。它释放指针指向的内存这是不正确的,或者至少非常错误