使用free释放嵌套struct导致程序崩溃,求问题排查分析
C语言嵌套结构体内存管理崩溃问题分析与修复
你的程序只输出Sucess1就终止,核心原因是指针传递方式错误导致的野指针访问,后续代码根本没机会执行。下面逐一拆解问题并给出修复方案:
1. 致命错误:Init函数的指针传值问题
C语言参数传递是值传递,你在Init中接收的struct Outer *outer是main函数中outer指针的副本。当你执行outer = (struct Outer*) malloc(sizeof(struct Outer));时,仅修改了副本的地址,main里的原始outer指针依然是未初始化的野指针。
这导致main里调用Init后,执行outer->Var = 1时直接访问非法内存,程序瞬间崩溃,根本走不到Exit函数。
2. Exit函数的逻辑错误(次要但需修正)
即便Init函数正常工作,Exit里也存在多处问题:
- 判断
if(outer != NULL)却打印"outer is null",逻辑完全颠倒; - free(outer)后还去判断
outer != NULL || outer->inner != NULL,此时outer是悬空指针,访问它的成员属于未定义行为; - 进入
outer->inner != NULL分支时打印"inner is null",内容与逻辑矛盾。
3. 内存分配检查顺序错误
Init里先分配outer和inner再检查空指针,若outer分配失败得到NULL,后续执行outer->inner = malloc(...)会直接访问NULL指针触发崩溃。正确顺序应该是先分配outer,检查成功后再分配inner。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> struct Outer { int Var; struct Inner { int Var; }*inner; }; // 改用指针的指针修改main中的原始指针 int Init(struct Outer **outer) { *outer = (struct Outer*) malloc(sizeof(struct Outer)); if(*outer == NULL){ printf("fail1: outer malloc failed\n"); return 1; } (*outer)->inner = (struct Inner*) malloc(sizeof(struct Inner)); if((*outer)->inner == NULL){ printf("fail1: inner malloc failed\n"); free(*outer); // 分配失败时释放已分配的outer,避免内存泄漏 return 1; } printf("Sucess1\n"); return 0; } int Exit(struct Outer *outer) { if(outer != NULL) { printf("outer is not null\n"); if(outer->inner != NULL) { printf("inner is not null, freeing inner\n"); free(outer->inner); outer->inner = NULL; // 置空避免悬空指针 } free(outer); outer = NULL; } printf("Sucess2\n"); return 0; } int main() { struct Outer *outer = NULL; // 初始化指针为NULL,避免野指针 if(Init(&outer) != 0){ return 1; } outer->Var = 1; outer->inner->Var = 2; Exit(outer); printf("terminated\n"); return 0; }
关键修复点说明
- Init函数改用
struct Outer **outer(指针的指针),直接修改main中原始指针的地址; - 调整内存分配检查顺序,分配失败时释放已分配内存,避免泄漏;
- 修正Exit函数的打印逻辑与悬空指针问题,释放后将指针置空;
- main中初始化outer为NULL,从根源避免野指针。
内容的提问来源于stack exchange,提问作者TheTrueJerome
相关产品推荐
相关产品推荐

