内存管理的艺术
专题五:内存管理的艺术。包括以下章节:
- 动态内存分配
- 程序中的三国天下
- 程序的内存布局
- 头疼的野指针
- 经典错误,你犯了吗?
- 交通规则,还是应该遵守
程序文件的一般布局
代码在可执行程序中的对应关系
程序的内存布局
- 文件布局在内存中映射
各个段的作用
- 堆栈段在程序运行后才正式存在,是程序运行的基础
- .bss段存放的是未初始化的全局变量和静态变量
- .text段存放的是程序中的可执行代码
- .data段保存的是那些已经初始化了的全局变量和静态变量
- .rodata段存放程序中的常量值,如字符串常量
- 窃以为:局部变量在可执行文件中(程序还没有运行,是一个可执行的二进制文件)时,是在.text段中。只有在运行时(程序已经加载到内存中),且调用了该局部变量所在的函数时,才从.text段中映射到内存中的栈空间;而没有调用函数时,局部变量仍在内存的.text(代码段)段空间。
程序术语对应关系
- 静态存储区通常指程序中的.bss和.data段
- 只读区通常指程序中的.rodata段
- 局部变量所占空间为栈上空间
- 动态空间为堆中的空间
- 程序可执行代码存放于.text段
- 问题:函数的地址对应程序的哪个段?//.text段(代码段)
课后思考
同是全部变量和静态变量,为什么初始化的和未初始化的保存在不同段中?
-C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
-为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
-而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。