#include <stdio.h>
#include <stdlib.h>
// 假设的复杂嵌套结构体
typedef struct Inner {
int value;
struct Inner *next;
} Inner;
typedef struct Outer {
Inner *innerPtr;
int outerValue;
struct Outer *nextOuter;
} Outer;
// 内存分配和初始化函数
Outer* createOuter() {
Outer *newOuter = (Outer*)malloc(sizeof(Outer));
if (newOuter == NULL) {
perror("malloc Outer");
return NULL;
}
newOuter->outerValue = 0;
newOuter->nextOuter = NULL;
Inner *newInner = (Inner*)malloc(sizeof(Inner));
if (newInner == NULL) {
perror("malloc Inner");
free(newOuter);
return NULL;
}
newInner->value = 0;
newInner->next = NULL;
newOuter->innerPtr = newInner;
return newOuter;
}
// 释放内存函数
void freeOuter(Outer *outer) {
if (outer == NULL) return;
Inner *currentInner = outer->innerPtr;
Inner *nextInner;
while (currentInner != NULL) {
nextInner = currentInner->next;
free(currentInner);
currentInner = nextInner;
}
free(outer);
}
int main() {
Outer *myOuter = createOuter();
if (myOuter != NULL) {
// 使用数据结构
freeOuter(myOuter);
}
return 0;
}
避免内存泄漏问题
- 每次分配内存后检查返回值:在使用
malloc
等内存分配函数后,立即检查返回值是否为NULL
。如果是NULL
,说明内存分配失败,应及时处理,例如释放已分配的内存并返回错误。如在createOuter
函数中,对malloc Outer
和malloc Inner
的返回值都进行了检查。
- 确保释放所有已分配的内存:在数据结构不再使用时,要确保调用释放内存的函数(如
freeOuter
),并在释放内存时按照正确的顺序释放。先释放内层结构体的内存,再释放外层结构体的内存。
处理指针悬空情况
- 释放内存后将指针置为
NULL
:在调用free
释放内存后,立即将指向已释放内存的指针置为NULL
。这样可以避免后续代码无意中使用悬空指针。在上述代码中,虽然没有直接在释放内存后置NULL
,但可以在freeOuter
函数中添加相关代码,如在free(outer)
后添加outer = NULL
。
- 避免在释放内存后使用指针:确保在释放内存后,不再通过原指针访问已释放的内存。例如,在调用
freeOuter(myOuter)
后,不再使用myOuter
指针。