跳到主要内容

动态存储

动态存储用于在程序运行时按需申请和释放内存。C 语言中常用 malloccallocreallocfree 管理堆内存。

一、栈和堆

区域特点
自动分配和释放,适合局部变量
手动申请和释放,适合动态数据

栈空间通常较小,大对象或生命周期不确定的数据应考虑放在堆上。

二、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
  • 明确内存所有权。

八、练习

  • 动态创建数组。
  • 实现动态扩容顺序表。
  • 实现链表插入和删除。
  • 检查程序是否存在内存泄漏。