C++程序在执行时,将内存大方向划分为5个区域(映射区一般提的比较少)
程序运行之前:
-
代码区 :存放函数体的二进制代码,由操作系统进行管理的
-
存放CPU执行的机器指令
-
代码区是共享的,只读的
-
-
全局区(静态存储区) :存放已初始化的全局变量和静态变量以及常量(其实又分为字符串常量和全局常量)
-
const修饰的全局变量放在全局区,const修饰的局部变量属于局部变量放在栈区中;
-
该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量(包含全局静态变量和局部静态变量)和常量数据(如字符串常量)(常量区的数据一旦初始化,不能修改,只读的内存);
-
-
BBS区未初始化全局区 :存入的是全局未初始化变量和未初始化静态变量
- 未初始化数据区的数据在程序开始执行之前被内核初始化为0或者为空。
- 因此也可以并入全局区
-
映射区 :存储动态链接库以及调用mmap函数进行的文件映射
程序运行之后:
-
栈区 ︰由编译器自动分配释放,存放函数的参数值,局部变量,局部常量
不要返回局部变量的地址,因为局部变量在作用域之后就释放了
-
堆区 :由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
内存四区意义: 不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
全局变量和静态变量的初始化
如果全局变量和静态变量在编译的时候已经初始化了,就直接初始化,如果没有初始化,那么就会默认初始化,无论是程序员初始化还是编译器初始化都是只初始化一次。总结下,class等这些全局变量是在main函数之前,在__tmainCRTStartup(main函数之前调用的函数)里调用的构造函数进行初始化;而像int等已知类型的已初始化全局变量和静态变量它的值已经写在PE文件里了,PE Loader加载时就已经写入,未初始化的全局和静态变量则也是在PE加载时为其分配空间,并初始化成0.具体我们要看下PE加载逻辑了。