概述

C 语言的内存管理是系统编程的核心技能。与高级语言不同,C 不提供自动垃圾回收,程序员需要手动管理内存的分配和释放。

内存区域划分

C 程序运行时的内存分为以下几个区域:

栈区(Stack)

  • 由编译器自动管理
  • 存储局部变量、函数参数、返回地址
  • 分配释放速度极快,遵循 LIFO 原则
  • 大小有限,通常默认 1~8 MB

堆区(Heap)

  • 由程序员手动管理
  • 使用 malloc/calloc/realloc 分配,free 释放
  • 空间大,但容易产生碎片
  • 分配失败时返回 NULL

全局/静态区(Data Segment)

  • 存储全局变量和 static 变量
  • 程序启动时分配,程序结束时释放
  • 分为已初始化段(.data)和未初始化段(.bss)

代码区(Text Segment)

  • 存储编译后的机器指令
  • 只读,防止程序意外修改自身代码

核心函数

函数 功能 头文件
malloc(size) 分配指定字节数的内存,不初始化 stdlib.h
calloc(n, size) 分配 n*size 字节并初始化为 0 stdlib.h
realloc(ptr, size) 调整已分配内存的大小 stdlib.h
free(ptr) 释放之前分配的内存 stdlib.h

常见错误

内存泄漏
分配后忘记释放,导致程序持续占用内存。

悬空指针
释放内存后继续使用指针,指向已回收的地址。

重复释放
对同一块内存调用 free 两次,导致未定义行为。

越界访问
访问分配区域之外的内存,可能破坏堆元数据。

分配失败未检查
malloc 返回 NULL 时未检查,直接解引用导致崩溃。

最佳实践

  • malloc 后立即检查返回值
  • free 后将指针置为 NULL
  • 谁分配谁释放,保持所有权清晰
  • 使用工具如 Valgrind 检测内存问题
  • 考虑使用内存池减少碎片