C语言结构体中堆分配指针的释放机制解析及相关疑问
关于C语言NODE结构体内存释放的问题
先明确你的代码定义:
结构体与函数定义
typedef struct tNODE { struct tNODE* parent; char* tag; }NODE;
NODE* new_node(NODE* parent){ NODE* result = malloc(sizeof(NODE)); result->inner_text = NULL; // 注:结构体未定义inner_text成员,此处应为笔误 result->parent = parent; return result; // 原代码遗漏return语句,补充后函数才符合逻辑 }
两种tag赋值方式
第一种直接赋值字符串常量:
NODE* temp = new_node(parent); temp->tag = "x";
第二种通过strdup分配内存:
NODE* temp = new_node(parent); temp->tag = strdup("x");
问题1:为什么strdup的tag可以free,直接赋值的不行?new_node不是已经分配内存了吗?
- 首先要明确:
new_node分配的是NODE结构体本身的堆内存,但结构体里的tag只是一个指针变量,它指向的内存和结构体内存是完全独立的两块区域。 - 直接赋值
"x"时,"x"是字符串常量,存储在程序的只读数据段,不是通过malloc/strdup这类堆内存分配函数创建的。free只能释放由malloc/calloc/realloc/strdup(内部调用malloc)分配的堆内存,对只读数据段的内存调用free属于非法操作,会触发崩溃等未定义行为。 - 而
strdup("x")会在堆上复制一份"x"的内容,返回堆内存地址,这块内存属于你主动分配的,因此可以用free释放。
问题2:用第一种赋值方式,free(temp)时tag会被一并释放吗?
不会。free(temp)只会回收new_node里malloc出来的NODE结构体本身的堆内存,但tag指向的是只读数据段的字符串常量,这块内存由程序启动时加载管理,不属于你分配的堆内存,不需要手动释放,也不会被free(temp)影响。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

