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