C进程的内存布局
每一个C语言进程都有一片结构相同的虚拟内存
每一个C语言进程都会包含下面的区域:
- 栈(stack)
- 堆(heap)
- 数据段
- 代码段
所谓虚拟内存,就是从实际物理内存映射出来的地址规范范围,他们的特征是
所有虚拟内存布局都是相同的

命令行参数
程序编译完成后,运行的指令就是 命令行参数
- argc 参数个数
- argv 数组 包含了所有命令行指令

- 对于全局变量 -- 全局变量也是静态变量
- 未初始化存放在数据段.bss处
- 未初始化的数据会自动清零
- 有初始化存放在数据段.data处
- 对于常量,存储在数据段.rodata处
- 对于静态数据(属于全局),存放在数据段中
- 静态数据只会声明一次
- 不随着函数的结束而结束
- 只会在程序退出时才会释放
- 未初始化存放在数据段.bss处
- 对于局部变量(存放在栈中)
栈内存
- 什么东西存储在栈内存中?
- 环境变量
- 命令行参数
- 局部变量(包括形参)
- 栈内存的特点
- 空间有限
- 不能用来存储尺寸太大的变量
- 每当一个函数被调用,栈就会向下增长一段
- 用以存储该函数的局部变量
- 每当一个函数退出,栈就会向上缩减一段
- 将该函数的局部变量所占的内存归还给系统
- 空间有限
如果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修饰的局部变量会提升到数据段中,由临时数据变成静态数据
- 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)
- calloc申请的内存空间会被自动清零
- malloc()实现
- 堆空间数据用完后需要回收
- free()方法
- 接受指向对空间的指针 free(p1)
- 回收完堆空间需要对野指针赋空值
- free()方法

Comments NOTHING