动态存储
动态存储用于在程序运行时按需申请和释放内存。C 语言中常用 malloc、calloc、realloc 和 free 管理堆内存。
一、栈和堆
| 区域 | 特点 |
|---|---|
| 栈 | 自动分配和释放,适合局部变量 |
| 堆 | 手动申请和释放,适合动态数据 |
栈空间通常较小,大对象或生命周期不确定的数据应考虑放在堆上。
二、malloc
int *arr = malloc(sizeof(int) * 10);
if (arr == NULL) {
return 1;
}
free(arr);
arr = NULL;
malloc 不会初始化内存内容。
三、calloc
int *arr = calloc(10, sizeof(int));
calloc 会把申请到的内存初始化为 0。
四、realloc
int *new_arr = realloc(arr, sizeof(int) * 20);
if (new_arr != NULL) {
arr = new_arr;
}
注意不要直接写:
arr = realloc(arr, new_size);
如果失败,原指针会丢失,导致内存泄漏。
五、free
free 用于释放堆内存。
注意:
- 只能释放动态申请的内存;
- 同一块内存不能释放两次;
- 释放后指针最好置为
NULL; - 释放后继续访问会导致悬空指针问题。
六、常见错误
- 内存泄漏;
- 重复释放;
- 越界访问;
- 使用未初始化内存;
- 释放栈内存;
realloc使用错误;- 指针释放后继续使用。
七、调试建议
- 编译时打开警告。
- 使用 AddressSanitizer。
- 使用 Valgrind。
- 每个
malloc都要有对应free。 - 明确内存所有权。
八、练习
- 动态创建数组。
- 实现动态扩容顺序表。
- 实现链表插入和删除。
- 检查程序是否存在内存泄漏。