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

如何正确释放双指针指向的结构体内存?及代码错误排查

如何正确释放双指针指向的结构体内存?

咱们来看看你遇到的这个问题,先把你的代码和编译报错贴出来:

原错误代码

// 释放与handle参数指向的Item相关的所有动态分配内存
// 并将Item指针设置为NULL
void deleteItem(Item** item) {
    free(item->name);
    free(item);
    *item = NULL;
}

编译错误信息

make gcc -c item.c -g -Wall
item.c: In function ‘deleteItem’:
item.c:48:12: error: request for member ‘name’ in something not a structure or union
free(&item->name);
^
Makefile:1...

为啥会报错?

你这里踩了个二级指针的常见坑:item是二级指针(Item**类型),它指向的是一个Item*指针,而不是直接指向结构体实例。所以直接写item->name的时候,编译器会困惑:你这是要访问一个指针的name成员?但指针本身不是结构体/联合体啊!这就是报错的核心原因。另外,free(item)也是错的——item是函数的参数(存在栈上),你要释放的是它指向的那个Item实例,也就是*item,而不是参数本身。

正确的实现方式

你需要先对二级指针item做一次解引用,拿到它指向的Item*(一级指针),然后再访问结构体的name成员。同时加上空指针检查,避免崩溃。修正后的代码如下:

void deleteItem(Item** item) {
    // 先做防御性检查:如果传入的二级指针是空,或者它指向的一级指针是空,直接返回
    if (item == NULL || *item == NULL) {
        return;
    }
    // 先释放结构体内部的动态分配内存(name字符串)
    free((*item)->name);
    // 再释放结构体实例本身的内存
    free(*item);
    // 把原指针置为NULL,避免调用方后续访问野指针
    *item = NULL;
}

关键步骤拆解

  • 空指针检查:这是防御性编程的好习惯,避免传入空指针时解引用导致程序崩溃。
  • (*item)->name:先通过*item拿到指向结构体的一级指针,再用->访问name成员,释放这个动态分配的字符串内存。
  • free(*item):释放结构体实例本身的内存,因为*item才是指向这个实例的指针。
  • *item = NULL:把调用方传入的那个一级指针置为NULL,这样调用方就不会再访问已经被释放的内存(彻底杜绝野指针问题)。

内容的提问来源于stack exchange,提问作者Broque

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:54:48