参考链接:
C++-内存管理_skrskr66的博客-CSDN博客_c++内存管理
C++内存管理(超长,例子很详细,排版很好)--CSDN博客_c++ 内存管理
具体查看第二条参考链接,真的超长但是很详细讲的很清楚
我看的好困,今天先这样吧。
1、C++中内存分为哪几部分?
在C++中,内存分为5个区。
栈、堆、自由存储区、全局/静态存储区和常量存储区
1、栈
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
2、堆
就是那些由new分配的内存块,他们的释放编译器不管,由我们应用程序去控制,一般一个new就有对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3、自由存储区
就是由malloc等分配的内存块,它和堆十分相似,不过它是用free来结束生命的。
4、全局/静态存储区
全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化和未初始化的,在C++里没有这个区分了,它们共同占用同一块内存区。
5、常量存储区
这是一块比较特殊的存储区,它们里面存放的是常量,不允许修改。
2、堆和栈的区分
举了个例子
int *p = new int[5];
new分配了一块堆内存,而指针p分配了一块栈内存
所以,这句话的意思是:
在栈内存存放了一个指向堆内存的指针p。
程序会先在堆中分配内存大小,调用operator new分配内存。再返回这块内存的首地址,放入栈中。
而这里在释放p的过程中,并不是delete p,而是delete []p
3、堆和栈有什么区别?
1、管理方式不同
对于栈来讲,是由编译器自动管理,无需我们手工控制;
对于堆来讲,释放工作由程序员控制,容易产生memory leak(内存泄漏)。
2、空间大小不同
一般来讲在32位系统下,堆内存可达4G空间。
但是对于栈来讲,一般都是有一定空间大小的,例如在VC6下面,默认的栈空间大小是1M。
但是栈孔令建也是可以修改的:
打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。
注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。
3、能否产生碎片不同
对于堆来讲,频繁地new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。
对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容就已经被弹出了。
4、生长方向不同
对于堆来讲,生长方式是向上的,也就是向着内存地址增加的方向;
对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
这是从链接中蹭的图:
5、分配方式不同
堆都是动态分配的,没有静态分配的堆。
栈有两种分配方式:静态和动态分配。
静态由编译器完成,比如局部变量的分配。
动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需我们手工实现。
6、分配效率不同
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址。压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。
堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法在堆中搜索可用的足够大小的空间,如果没有足够大小的空间(可能由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然堆的效率比栈要低很多。