C语言入门 – 内存管理

LongGuan_admin 发布于 9 小时前 6 次阅读


C进程的内存布局

每一个C语言进程都有一片结构相同的虚拟内存

每一个C语言进程都会包含下面的区域:

  • 栈(stack)
  • 堆(heap)
  • 数据段
  • 代码段

所谓虚拟内存,就是从实际物理内存映射出来的地址规范范围,他们的特征是

命令行参数

程序编译完成后,运行的指令就是 命令行参数

  • argc 参数个数
  • argv 数组 包含了所有命令行指令
  • 对于全局变量 -- 全局变量也是静态变量
    • 未初始化存放在数据段.bss处
      • 未初始化的数据会自动清零
    • 有初始化存放在数据段.data处
    • 对于常量,存储在数据段.rodata处
    • 对于静态数据(属于全局),存放在数据段中
      • 静态数据只会声明一次
      • 不随着函数的结束而结束
      • 只会在程序退出时才会释放
  • 对于局部变量(存放在栈中)

栈内存

  • 什么东西存储在栈内存中?
    • 环境变量
    • 命令行参数
    • 局部变量(包括形参)
  • 栈内存的特点
    • 空间有限
      • 不能用来存储尺寸太大的变量
    • 每当一个函数被调用,栈就会向下增长一段
      • 用以存储该函数的局部变量
    • 每当一个函数退出,栈就会向上缩减一段
      • 将该函数的局部变量所占的内存归还给系统

如果SIZE 大小超过8M(1024*1024*8),那么执行的时候直接段错误,因为栈溢出

    char buf[1024 * 1024 * 8];
    buf[1024 * 1024 * 8 - 1] = 100;
    printf("%d \n", buf[1024 * 1024 * 8 - 1]);

静态数据

  • 全局变量
    • 定义在函数外部的变量
  • 静态局部变量
    • static修饰的局部变量会提升到数据段中,由临时数据变成静态数据
      • 静态数据只会声明一次
      • 不随着函数的结束而结束
      • 只会在程序退出时才会释放
    • 定义在函数内部,且被static修饰的变量
      • 只能在当前文件访问
      • static修饰函数表示该函数只有当前文件可以访问
  • static修饰全局变量
    • 使之由各文件可见的静态数据,变成了本文件可见的静态数据。

堆内存

  • 堆内存的基本特征:
    • 相比于栈内存,堆的总大小仅受限于物理内存,在物理内存允许的范围内,系统对堆内存的申请不做限制
    • 相比于栈内存,堆内存从下往上增长
    • 堆内存是匿名的,只能通过指针访问;
      • 想让这段堆内存是什么类型,就使用什么类型的指针接受molloc返回值
    • 自定义分配的堆内存,除非开发者主动释放,否则永远不释放,直到程序退出
    //申请一段堆内存存放 int 类型的数据
    void * malloc(size_t size) //参数size 想申请的内存字节数
    //返回值 void *  (返回申请好的堆内存的基地址)
    // 成功:返回地址 失败:NULL
    
    int *p = malloc(sizeof(int));
    
    • 可以作为变长数组的替代方案
    int len
    sacnf %d,&len  //输入指定的数组长度
    
    //int arr[len]   变长数组兼容性差,不适合大内存数据
    int * arr = malloc(sizeof(int) * len)

    堆内存的申请和释放以及相关API

    • 堆内存的申请 malloc()/ calloc()
      • malloc()实现
        • malloc申请的内存空间不会被自动清零
      • calloc()实现
        • calloc申请的内存空间会被自动清零
          • 参数一 成员数量
          • 参数二 成员大小
          • int *p2 = calloc(10,sizeof(int))
          • int *p2 = calloc(sizeof(int),10)
          • int *p2 = calloc(sizeof(int) * 10,1)
    • 堆空间数据用完后需要回收
      • free()方法
        • 接受指向对空间的指针 free(p1)
      • 回收完堆空间需要对野指针赋空值
    此作者没有提供个人介绍。
    最后更新于 2026-01-15