C 正确释放动态分配的结构

C 正确释放动态分配的结构,c,pointers,struct,C,Pointers,Struct,我已经读过一些关于类似问题的答案,但有一点使我的案例与我读到的略有不同。我使用一个链表来存储线程拾取和处理的数据。节点是一个简单的typedef struct QueueNode; typedef struct QueueNode { struct QueueNode* next; // pointer to the next node void* data; } QueueNode; 名单 typedef struct LinkedQueue { QueueNode

我已经读过一些关于类似问题的答案,但有一点使我的案例与我读到的略有不同。我使用一个链表来存储线程拾取和处理的数据。节点是一个简单的
typedef

struct QueueNode;

typedef struct QueueNode {
    struct QueueNode* next; // pointer to the next node
    void* data;
} QueueNode;
名单

typedef struct LinkedQueue {
    QueueNode* head;   // pointer to the first Node
    QueueNode* tail;   // pointer to the last Node
    long long k;       // the number of nodes in the queue
} LinkedQueue;
两者都由使用
malloc
的相应函数初始化。当线程需要处理数据时,它调用一个函数,该函数弹出队列的头部并返回
void*data
指针

void* pop_data(LinkedQueue* queue) {
    /*
     Pops the head node from a queue, extracts data out of it and
     frees the memory allocated by that node
     */
    assert(queue->head && "Can't pop data from an empty queue");

    void* data = queue->head->data;            // extract data from head
    QueueNode* old_head_pointer = queue->head;
    queue->head = queue->head->next;           // replacing head with a new one
    destroy_node(old_head_pointer);            // destroying the old head

    return data;
};
问题是,
destroy\u node
应该释放分配给节点的内存,而不会破坏
void*data
指针,因为这些数据会在以后使用。这就是我的情况变得不同的原因。我已经读过的所有示例都描述了完全释放节点内所有内容的情况,而我需要保存一个指针

void destroy_node(QueueNode* node) {
    /*
     Frees memory allocated by a node.
     */
    free(node->next);
    free(node);
};

在我的测试中,这很好,但因为我知道
free()
实际上不会擦除内存,而且我的机器有大量内存,所以我仍然可以访问
void*data
指针,而不会出现任何分段错误,这一事实是不可靠的。所以问题基本上是我做得对还是我的担心真的合理?如果这确实可能导致内存泄漏或其他与内存相关的问题,我该如何做呢?

您做得对,因为您在释放整个节点之前正在访问
数据
指针。做相反的事情将是一个逻辑错误。 如果您以后在代码中的某个地方释放数据,则不会出现内存泄漏


但是,您不应该释放节点的
next
字段,因为它也会使该节点无效,这可能不是您想要做的

在释放整个节点之前访问
数据
指针,这样做是正确的。做相反的事情将是一个逻辑错误。 如果您以后在代码中的某个地方释放数据,则不会出现内存泄漏


但是,您不应该释放节点的
next
字段,因为它也会使该节点无效,这可能不是您想要做的

在释放整个节点之前访问
数据
指针,这样做是正确的。做相反的事情将是一个逻辑错误。 如果您以后在代码中的某个地方释放数据,则不会出现内存泄漏


但是,您不应该释放节点的
next
字段,因为它也会使该节点无效,这可能不是您想要做的

在释放整个节点之前访问
数据
指针,这样做是正确的。做相反的事情将是一个逻辑错误。 如果您以后在代码中的某个地方释放数据,则不会出现内存泄漏


但是,您不应该释放节点的
next
字段,因为它也会使该节点无效,这可能不是您想要做的

如果要保留指向“数据”的指针

然后在调用“destroy_node()”之前将该指针保存到局部变量中

destroy_node()函数对“void*Data”指向的内存没有任何影响

正如其他地方提到的,不要释放()下一个指针,因为这实际上释放了链表中的下一个节点(head刚刚设置为指向该节点)

这意味着“head”现在指向未分配的内存

对未分配内存的任何引用都会导致未定义的行为

这种未定义的行为可能导致任何情况,包括seg故障事件

所有编译操作都应在启用most/All警告的情况下执行

启用警告后,发布的代码将引发2个警告

每个警告都说:

ISO C does not allow extra ';' outside of a function

如果要保留指向“数据”的指针

然后在调用“destroy_node()”之前将该指针保存到局部变量中

destroy_node()函数对“void*Data”指向的内存没有任何影响

正如其他地方提到的,不要释放()下一个指针,因为这实际上释放了链表中的下一个节点(head刚刚设置为指向该节点)

这意味着“head”现在指向未分配的内存

对未分配内存的任何引用都会导致未定义的行为

这种未定义的行为可能导致任何情况,包括seg故障事件

所有编译操作都应在启用most/All警告的情况下执行

启用警告后,发布的代码将引发2个警告

每个警告都说:

ISO C does not allow extra ';' outside of a function

如果要保留指向“数据”的指针

然后在调用“destroy_node()”之前将该指针保存到局部变量中

destroy_node()函数对“void*Data”指向的内存没有任何影响

正如其他地方提到的,不要释放()下一个指针,因为这实际上释放了链表中的下一个节点(head刚刚设置为指向该节点)

这意味着“head”现在指向未分配的内存

对未分配内存的任何引用都会导致未定义的行为

这种未定义的行为可能导致任何情况,包括seg故障事件

所有编译操作都应在启用most/All警告的情况下执行

启用警告后,发布的代码将引发2个警告

每个警告都说:

ISO C does not allow extra ';' outside of a function

如果要保留指向“数据”的指针

然后在调用“destroy_node()”之前将该指针保存到局部变量中

destroy_node()函数对“void*Data”指向的内存没有任何影响

正如其他地方提到的,不要释放()下一个指针,因为这实际上释放了链表中的下一个节点(head刚刚设置为指向该节点)

这意味着“head”现在指向未分配的memor