C语言程序的内存映像
C源程序经过编译和链接后,成为二进制形式的可执行文件,称为程序映像。可执行文件的采用ELF格式----可执行链接格式存储,内容包含程序指令、已初始化的静态数据和其他一些信息,例
如为初始化的静态数据空间大小、符号表、调试信息、动态共享库的链接表等。可执行文件的映像如下(真实的内存分配地址并不如此):所有讨论也仅仅站在程序员的角度。
*************************
* 命令行数据 *
* 环境变量数据 *
*************************
* 栈 *
* ( stack ) *
* . *
* . *
* . *
* *
*--------------------------- --*
* 堆 *
* ( heap ) *
* . *
* . *
* . *
* *
* *
* *
*************************
* *
* 未初始化的数据 *
* (bss) *
*************************
* *
* 已初始化的数据 * 除一般的静态、全局对象(变量外),
* (data) * 也包括字符串等常量。
*************************
* * 对于基本类型的常量可以编进代码。
* 代码段 *
* text *
*************************
当然有的书本分类为:
1.全局、静态数据区
2.常量数据区
3.代码区
4.栈区
5.堆区
测试程序分析(X86(32bit)):
可能的顺序:(低--->高)
命令行--->代码段--->栈--->堆--->已初始化data---->未初始化bss
\ /
\ /
常量区位于这两者之间
说明:
1.一般来说,一个程序使用栈的大小是固定的,由编译器决定,VC下默认情况下一般是1M,但可以手动的去改变。
2.关于效率:栈上的内存是系统自动分配的,压栈和出栈都有相应的指令进行操作,因此效率较高,关键分配的内存空间是连续的,不会产生内存碎片。
堆上的内存是由开发者来动态分配和回收的。当开发人员通过new和malloc申请堆上的内存时,系统需要按一定的算法在堆空间寻找合适大小的空闲堆,并修改相应的链表。因此效率低,容易产生碎片(当然包括内碎片和外碎片).