You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双向链表内存未完全释放问题:调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 14:25:28