一、内存结构简介
C/C++的内存结构,主要分为五个区域:栈、堆、自由存储区、全局/静态存储区、常量存储区。
内存区域划分如图:
扩展链接
堆栈大小设置
1、内存分布
- 栈:
编译器和操作系统自动完成内存空间的分配和释放。
优点:执行效率很高,使用方便【栈内存分配运算内置于处理器的指令集中】。
缺点:分配的内存容量有限,分配失败会提示栈错误。
注意,const局部变量也储存在栈区内,栈区向地址减小的方向增长。
- 堆
程序员向系统申请分配空间,当系统收到程序的申请时,会遍历一个记录空闲内存地址的链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。
缺点:分配速度慢,地址不连续,容易碎片化,容易造成内存泄漏。
- 自由存储区
1、管理机制和堆类似;
2、区别就是由malloc分配内存,由free来释放。
- 全局/静态存储区
全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,
在C++里面没有这个区分了,他们共同占用同一块内存区。
- 常量存储区
这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
2、堆栈的区别
- 举个栗子
void fun(){
int* p = new int[5];
}
指针p存储在栈中,new()分配了一段堆空间。即栈中存储了一个p指针,指向一块堆内存空间。
- 区别
1、管理方式:栈由编译器自动管理;堆由用户控制,容易产生内存泄漏。
2、空间大小:一般来说,对于32位系统下,堆内存空间可以达到4G(2的32次方).从这个角度来看堆的空间是非常大的. 而对于栈空间来说,大小是有限的. 大概2MB.
3.、碎片问题:频繁的new/delete会造成内存空间不连续,产生大量碎片,使程序效率降低。栈不会产生碎片,因为栈是先进后出的队列。
4.、生长方向:栈的生长方向是向下,即内存地址减小的方向;堆的生长方向是向上,即内存地址增加的方向。
5.、分配方式:栈有静态分配和动态分配两种方式:静态分配是编译器自动跟配,比如局部变量;动态分配由alloca函数进行分配。栈分配的空间都由编译器释放。
6.、分配效率:
栈的效率很高:栈是机器系统提供的数据结构,计算机底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈和出栈都有专门的指令集。
堆的效率很低:堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
【注意】无论堆栈都要防止产生越界,因为越界的结果很严重,要么程序崩溃,要么程序的堆栈结构被破坏,产生意想不到的结果。