双向链表内存未完全释放问题:调用clearboard后仍有Item2残留
双向链表内存未完全释放问题:调用clearboard后仍有Item2残留
嘿,我看了你的问题和代码,其实你遇到的不是“内存没完全释放”的问题,而是释放内存后还在访问野指针导致的未定义行为——那些残留的"Item2"并不是内存没被释放,而是你释放后,原来的内存区域暂时还没被系统覆盖,刚好保留了之前的字符串内容而已。
问题根源分析
你的clearboard函数其实已经正确遍历并释放了所有List和Item结构体的内存,但有个关键疏漏:
- 释放完所有链表节点后,你没有把传入的
*board指针置为NULL。这就导致main函数里的board变量仍然指向已经被释放的内存地址(原来的List4的位置)。 - 当你调用
printboard(board)时,程序会从这个野指针开始遍历,读取已经被释放的List和Item的内存内容——这属于C语言里的未定义行为,系统可能返回乱码,也可能刚好返回之前残留的数据(比如你看到的"Item2"),完全取决于内存的当前状态。
解决方法
只需要修改clearboard函数,在最后加上一行*board = NULL;,把根指针置空,这样后续调用printboard时,因为current一开始就是NULL,会直接跳过遍历循环,不会再访问已释放的内存:
void clearboard(List** board) { List* currentList = *board; while (currentList != NULL) { Item* currentItem = currentList->firstitem; while (currentItem != NULL) { Item* temp = currentItem; currentItem = currentItem->nextitem; free(temp); } List* tempList = currentList; currentList = currentList->nextList; free(tempList); } *board = NULL; // 加上这行,把根指针置空 }
额外提醒
其实在释放内存后,你不应该再去访问那些已经被释放的内存区域,这本身就是错误操作——你的测试方式(释放后打印)本身就会触发未定义行为。如果要验证内存是否正确释放,建议用专业的内存检测工具(比如Valgrind)来检查,而不是通过打印已释放的内存来判断。
备注:内容来源于stack exchange,提问作者A Mirdha
相关产品推荐
相关产品推荐

