常见内存错误
C 语言手动内存管理灵活但容易出错。以下是开发中最常见的内存错误及其解决方案,理解这些错误模式是编写健壮 C 代码的基础。
1. 使用未初始化内存
int *p = malloc(sizeof(int));
printf("%d\n", *p); /* 未定义:malloc 不初始化 */
/* 正确 */
int *p = calloc(1, sizeof(int)); /* 初始化为 0 */
/* 或 */
int *p = malloc(sizeof(int));
*p = 0;
2. 越界访问
int *arr = malloc(10 * sizeof(int));
arr[10] = 0; /* 越界!有效索引 0-9 */
/* 正确 */
for (int i = 0; i < 10; i++)
arr[i] = 0;
3. 释放后使用
int *p = malloc(100);
free(p);
*p = 10; /* 悬垂指针 */
/* 正确 */
free(p);
p = NULL;
4. 双重释放
int *p = malloc(100);
free(p);
free(p); /* 双重释放 */
/* 正确 */
free(p);
p = NULL; /* 再次 free(NULL) 是安全的 */
5. 内存泄漏
void process(void)
{
int *p = malloc(100);
/* 使用 */
if (error())
return; /* 泄漏! */
free(p);
}
/* 正确 */
void process(void)
{
int *p = malloc(100);
/* 使用 */
free(p); /* 统一释放 */
}
6. 不匹配分配释放
int *p = calloc(10, sizeof(int));
/* 使用 */
/* 不要假设用 free 就够了,虽然这里是对的 */
/* 错误示例 */
/* int arr[10]; free(arr); */ /* arr 不是堆分配的 */
7. 错误的 realloc 用法
int *p = malloc(100);
p = realloc(p, 200); /* 如果失败,原内存丢失 */
/* 正确 */
int *new_p = realloc(p, 200);
if (new_p != NULL)
p = new_p;
8. 整数溢出导致分配不足
int n = 1000000;
int *p = malloc(n * sizeof(int)); /* n * 4 可能溢出 */
/* 正确 */
int *p = malloc((size_t)n * sizeof(int));
/* 或检查 */
if (n > SIZE_MAX / sizeof(int)) {
/* 错误处理 */
}
最佳实践
- 分配后初始化
- 严格检查边界
- 释放后置 NULL
- 配对分配释放
- 用工具检测(Valgrind、ASan)
- 异常路径也要释放