本文主要介绍两点
1:C程序的存储区
2:堆和栈之间的区别及特点
1:C程序的存储结构
《UNIX高级编程》7.6节介绍了C程序存储区,如下图所示:
它分为:(从低地址向高地址依次排列)
1.正文段(text)
2.初始化数据段(data)
3.非初始化数据段(bss)
4.堆(heap)(由图中可以看出,堆是由低地址向高地址生长的)
5.栈(stack)(由图中可以看出,栈是由高地址向低地址生长的)
6.命令行参数和环境变量(command-line arguments and environment variables)
下面对此一一做出介绍:
正文段:也就是.text段。
CPU 执行的机器指令。
父进程和子进程之间可共享正文段。
存在于程序镜像文件中且只读, 由 exec 函数从程序镜像文件中读入内存, 例如在 shell 中正在执行的程序运行正文段的指令。
已初始化的数据:即.data段。
具有明确初始值的全局变量和静态变量
存在于程序镜像文件中,由 exec 函数从程序镜像文件中读入内存
未初始化数据段:即.bss段。
Block Started by Symbol, 即以符号开始的内存块
未初始化的数据可能是全局变量, 静态变量
bss段并不占用可执行程序的镜像的空间,而是在执行时分配内存,并由 exec 函数初始化为0, 例如声明全局数组 int a[100],不会将100个0记录在可执行文件镜像中,而只是记录了标识符a和其所占用的内存大小
变量的大小记录在符号表中,要分配的整个 bss段的大小记录在段表(Section headers)中。
对于全局变量而言,如果已经初始化了,则存放在初始化数据区中,否则就在未初始化数据段中。
堆和栈见下文介绍。
堆与栈之间有界限,其实在堆与栈之间还有一个区域,即共享库区域,比如平时用到的C库函数之类的就在这一个区域中。
命令行参数和环境变量
使程序了解进程环境,在执行时分配内存
在 shell 中执行某个程序(shell 的子进程)时,shell 进程调用 exec函数将命令行参数传递给要执行的程序
2:堆和栈
栈是由编译器自动分配并释放的,而堆是由程序员手动分配和释放的。
首先看以下代码:
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b; //栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; //123456\0在常量区,p3在栈上。
static int c = 0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一块。
}
2.1 堆和栈的特点
栈是操作系统提供的功能,特点是快速高效,缺点是对支持的数据有限制,一般是整数,指针,浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。而堆是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。
栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。
栈支持静态分配和动态分配两种,静态分配和释放由编译器完成,栈的动态分配无需释放,但栈的动态分配是不被鼓励的。堆的分配和释放都是动态的。
2.2 堆和栈的空间申请
栈空间是由编译器自动分配和释放的。
堆空间是用new运算符或malloc函数申请,对应的释放函数是delete运算符和free函数。
2.3 堆和栈申请内存后的系统响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出,栈不够用的情况一般是程序中分配了大量数组和递归函数层次太深。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2.4 堆和栈空间申请大小的限制
栈:是向低地址扩展的数据结构,是一块连续的内存的区域。空间大小是固定的。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
本文主要参考整理自:
http://blog.youkuaiyun.com/fanlu319/article/details/7769103
http://blog.youkuaiyun.com/why19911024/article/details/53033426