为什么在单链表中这样使用 free ?
Why using free like this in singly linked list?
typedef struct ListNode{
char data[4];
struct ListNode* link;
} listNode;
typedef struct{
listNode* head;
}linkedList_h;
void freeLinkedList_h(linkedList_h* L){
listNode *p;
while(L->head!=NULL){
p=L->head;
L->head=L->head->link;
free(p);
p=NULL;
}
}
这是我教科书的示例代码。在freeLinkedList_h中,为什么我们使用“p=NULL”?
如果 p
未设置为 NULL
,程序将更容易出现释放后使用错误。
这将更多地依赖于内存分配以及系统保护的具体实现。
通过将指针设置为 NULL
,程序更容易发生硬崩溃,在许多情况下,这比访问释放的内存更可取。对于自定义内存分配器,这可能更是如此,因为内存调试器可能并不总是能发现问题,具体取决于自定义内存实现。
对于使用默认 malloc
和朋友的普通程序,这是一个好的内存调试器无法捕捉到的。
但在某些情况下,“清理”不再需要的已用内存肯定是个好习惯。
假设在您的示例中,无论出于何种原因,另一个指针引用了链表节点,并且它试图访问例如next
成员,它不能再意外地工作了。
但如果这确实是作者的意图,他们应该已经澄清并且可能还首先执行了 memset(p, 0, sizeof *p);
。因此我倾向于说这不一定是好的做法。
我宁愿推荐使用内存调试器来捕获讨厌的错误,或者只在调试版本中添加额外的指令。
typedef struct ListNode{
char data[4];
struct ListNode* link;
} listNode;
typedef struct{
listNode* head;
}linkedList_h;
void freeLinkedList_h(linkedList_h* L){
listNode *p;
while(L->head!=NULL){
p=L->head;
L->head=L->head->link;
free(p);
p=NULL;
}
}
这是我教科书的示例代码。在freeLinkedList_h中,为什么我们使用“p=NULL”?
如果 p
未设置为 NULL
,程序将更容易出现释放后使用错误。
这将更多地依赖于内存分配以及系统保护的具体实现。
通过将指针设置为 NULL
,程序更容易发生硬崩溃,在许多情况下,这比访问释放的内存更可取。对于自定义内存分配器,这可能更是如此,因为内存调试器可能并不总是能发现问题,具体取决于自定义内存实现。
对于使用默认 malloc
和朋友的普通程序,这是一个好的内存调试器无法捕捉到的。
但在某些情况下,“清理”不再需要的已用内存肯定是个好习惯。
假设在您的示例中,无论出于何种原因,另一个指针引用了链表节点,并且它试图访问例如next
成员,它不能再意外地工作了。
但如果这确实是作者的意图,他们应该已经澄清并且可能还首先执行了 memset(p, 0, sizeof *p);
。因此我倾向于说这不一定是好的做法。
我宁愿推荐使用内存调试器来捕获讨厌的错误,或者只在调试版本中添加额外的指令。