Skip to content

好的,这里为你做一个精简版的总结,让你快速抓住C语言内存模型的要点:

C语言内存主要分区及其特点:

  1. 栈 (Stack) 区:

    • 放什么: 函数的局部变量、函数参数、函数调用的返回地址等。
    • 谁管: 编译器自动分配和释放。
    • 特点: 速度快,但空间有限。函数调用结束,里面东西就没了(“先进后出,后进先出”)。
    • 例子: void func() { int x = 10; } (x 就在栈上)
  2. 堆 (Heap) 区:

    • 放什么: 程序运行时动态申请的内存(比如用 malloccalloc 申请的)。
    • 谁管: 程序员手动申请 (malloc) 和释放 (free)。
    • 特点: 空间大,灵活,但分配/释放较慢。忘了 free 就会内存泄漏。
    • 例子: char *p = (char*)malloc(100); (p 指向的100字节在堆上,p 本身可能在栈或静态区)
  3. 静态存储区 (Static/Global Storage Area):

    • 放什么: 全局变量、静态变量 (static 修饰的变量,无论全局还是局部)。
    • 谁管: 程序启动时分配,程序结束时由系统释放。
    • 特点: 整个程序运行期间都存在。
    • 细分:
      • 数据段 (.data): 存放已初始化的全局变量和静态变量。
      • BSS 段 (.bss): 存放未初始化的全局变量和静态变量 (系统会自动给它们赋零值或空指针)。
    • 例子: int global_var = 1; static int static_var = 2;
  4. 常量存储区 (Constant Storage Area / .rodata):

    • 放什么: 字符串字面量 (如 "hello world")、用 const 修饰的全局变量 (通常情况下)。
    • 谁管: 程序启动时分配,程序结束时释放。
    • 特点: 通常是只读的,内容在程序运行期间不能修改。
    • 例子: const char *message = "Hello"; ("Hello" 在这里)
  5. 代码区 (Code Segment / .text):

    • 放什么: 程序的二进制机器指令。
    • 谁管: 操作系统。
    • 特点: 只读,可共享。

关键点回顾 (针对你的例子):

  • char *fun1() { char *str = "hello"; return str; }

    • "hello":在 常量区
    • str (指针变量本身):在 栈区 (函数执行完就没了)。
    • 返回安全:因为 "hello" 一直在,返回的地址有效。
  • char *fun2() { char str[] = "hello"; return str; }

    • str (数组内容 "hello"):在 栈区 (函数执行完就没了)。
    • 返回危险:因为数组 str 的内存会在函数返回后被回收,返回的地址指向一块无效的内存。
  • char *fun2_static() { static char str[] = "hello"; return str; }

    • str (数组内容 "hello"):在 静态存储区 (程序运行期间一直有效)。
    • 返回安全:因为 str 数组的内存一直存在。

一句话概括:

  • :临时工,干完活就走人,东西也带走。
  • :租来的仓库,自己管钥匙,用完得自己还,忘了还就一直占着。
  • 静态/全局区:公司的固定资产,从开张到倒闭都在。
  • 常量区:刻在石头上的规章制度,只能看不能改。

希望这个总结能帮你快速理解!