- 在循环中频繁分配内存
- 场景:在循环体内部进行内存分配操作,每次循环都会执行分配,导致大量不必要的内存分配与释放开销。例如:
for (int i = 0; i < n; i++) {
int *ptr = (int *)malloc(sizeof(int));
// 使用ptr
free(ptr);
}
int *ptr = (int *)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
// 使用ptr[i]
}
free(ptr);
- 函数中返回局部变量地址
- 场景:函数内部创建局部变量并返回其地址,当函数结束时,局部变量所在栈空间被释放,导致返回的指针成为野指针。例如:
int *func() {
int num = 10;
return #
}
- 避免方法:改为返回动态分配的内存地址,并在调用方负责释放。
int *func() {
int *ptr = (int *)malloc(sizeof(int));
*ptr = 10;
return ptr;
}
// 调用方
int *result = func();
// 使用result
free(result);
- 不必要的结构体嵌套分配
- 场景:在结构体中嵌套结构体,并且对每个嵌套的结构体都进行重复的分配操作。例如:
typedef struct {
int data;
} InnerStruct;
typedef struct {
InnerStruct inner;
InnerStruct *innerPtr;
} OuterStruct;
OuterStruct outer;
outer.innerPtr = (InnerStruct *)malloc(sizeof(InnerStruct));
- 避免方法:如果不需要指针指向内部结构体,可以直接使用内部结构体成员,避免额外的分配。
typedef struct {
int data;
} InnerStruct;
typedef struct {
InnerStruct inner;
} OuterStruct;
OuterStruct outer;
// 直接使用outer.inner
- 使用动态分配代替静态数组
- 场景:在已知数组大小且大小固定的情况下,仍然使用动态内存分配。例如:
int main() {
int *arr = (int *)malloc(10 * sizeof(int));
// 使用arr
free(arr);
return 0;
}
int main() {
int arr[10];
// 使用arr
return 0;
}