C语言单链表释放函数中free(p)后将p置为NULL的原因是什么
问题相关代码
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; } }
问题解答
free(p)的作用仅为释放p指向的内存空间,将这块内存的使用权交还给操作系统,不会修改指针p本身的存储值,执行free操作后p仍然指向原来的内存地址,此时的p属于野指针。此处添加p=NULL的作用主要有两点:
- 避免后续代码误访问已经被释放的内存:如果p被置为NULL,后续一旦出现非法解引用p的操作,绝大多数操作系统会直接触发段错误崩溃,可第一时间暴露代码问题;如果p保持野指针状态,解引用时可能读取到脏数据,甚至意外修改其他正在被使用的内存数据,这类隐性bug排查难度极高。
- 避免同一块内存被重复释放:如果后续逻辑存在
if(p!= NULL) free(p)的校验写法,p置为NULL后就不会触发重复释放问题,而重复释放会直接导致内存崩溃、数据损坏等严重故障。
额外补充:在这段示例代码的上下文里,p是while循环的局部变量,每次循环迭代时都会被重新赋值为新的L->head,这个场景下p=NULL的实际作用不大,属于教材为了培养开发者“内存释放后立刻置空对应指针”的编码习惯,刻意加入的规范写法。实际生产中这个上下文的置空操作可以省略,但养成释放后置空的习惯能大幅降低复杂代码场景下的内存bug概率。
内容的提问来源于stack exchange,提问作者qwerty
相关产品推荐
相关产品推荐

