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;
}
}
this is an example code of my textbook. In freeLinkedList_h, why we use "p=NULL"?
CodePudding user response:
If p
is not set to NULL
, the program will be a bit more susceptible for a use-after-free bug.
It will be much more dependent on the specific implementation of memory allocation as well as system protections.
By setting the pointer to NULL
the program is more likely to hard crash, which in many cases is preferred over accessing freed memory. With a custom memory allocator this might be even more true, because a memory debugger might not always catch a problem, depending on the custom memory implementation.
For a normal program using the default malloc
and friends, this is nothing a good memory debugger doesn't catch.
But there are definitely cases where it's good practice to "clean up" used memory that is no longer needed.
Say that in your example, for whatever reason another pointer had a reference to the linked list node, and it tried to access e.g. the next
member, it could no longer accidentally still work.
But if that is truly what the author intended, they should have clarified and probably also performed memset(p, 0, sizeof *p);
first. Therefore I am inclined to say it was not necessarily meant as good practice.
I would have rather recommended to use a memory debugger to catch nasty bugs, or to only add the extra instructions in debug builds.