笔试题集锦----内存分配种类
有关存储区的分配 ,C和C++是略有不同的。先来说说C的存储区
C的存储区分配划分
1、栈。由编译器自动分配释放,比如局部变量、函数参数、返回数据以及返回地址等等。
2、堆。由程序员分配释放,若程序员不释放,程序结束时由OS回收。分配方式类似于链表。
3、全局区(静态存储区)。这里存储的是全局变量以及静态变量。不过初始化的全局变量和静态变量存在一块区域内,未初始化的放到另一块区域内。程序结束时释放
4、文字常量区。这里存储的是一些常量,在程序结束的时候释放。
下面是配合例子说明内存分配的划分
int a = 0;//全局存储区,已初始化 char *pName;//全局存储区,未初始化 void FuncA() { int a; //栈 char name[] = "abcde";//栈 char *pNumber = "12345"; //pNumber存储在栈上,"12345"在文字常量区 static int b =2; //全局区(静态存储区,已经初始化) }
C++的存储区分配划分
(1)堆。
堆上的内存通常编译器不负责处理这块内存,由程序来控制。这里的内存由new来分配,用delete释放。如果忘记delete会引起内存泄漏,但是程序结束后操作系统会自动回收
例如 int *p = new int[5];
首先在堆上申请了存储5个int的数组,然后在栈上申请内存存储指针p,就是说在栈内存中存放了一个指向一块堆内存的指针p。如果释放这些内存呢?栈上的内存我们不用关心,编译器会自动处理,那在堆上申请的内存呢?delete p?p指向数组的首地址,也就是数组第一个变量的地址,所以delete p只删除了数组第一个变量的内存,并不能释放整个数组的内存,所以要delete []p,也就是说告诉编译器删除整个数组。
(2)栈。
栈上的内存由编译器直接负责处理,在编译器需要的时候就分配,不需要的时候就自动释放。例如函数的参数、局部变量等。
(3)自由存储区。
由malloc分配的内存,类似堆,但是释放由free完成。
自由存储区和堆并不完全是一回事,感兴趣的可以看这篇文章的分析 https://www.cnblogs.com/QG-whz/p/5060894.html
(4)全局/静态存储区。
全局变量和静态变量都放在这块内存中,这里的变量都会自动初始化。
(5)常量存储区。
这里面存储的是常量,理论上不允许修改。
下面说说不同存储区之间的差别
1、堆与栈
分配方式不同
空间大小不同
管理的方式不同
分配的效率不同
能否产生碎片不同
生长方向不同
分配方式:堆是动态分配的,没有静态分配。而栈分静态和动态分配两种方式。栈的静态分配由编译器完成,比如局部变量的分配;栈的动态分配由alloca函数进行分配,释放由编译器自动完成。
空间大小:在32位系统下,堆内存理论上可分配4G(2^32)大小,栈能分配的内存都是有限的,一般为几M。
管理方式:堆的申请和释放通过程序控制,如果不及时的释放就会造成内存泄漏(memory leak);而栈是由编译器自动处理的,无需我么们关心。
分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供专门的支持--设置专门的寄存器存放栈的地址,压栈出栈都会有专门的指令去完成,这就决定了栈的效率比较高。而堆是由C++函数库提供的,分配的方式比较复杂,比如在分配一块内存时,首先通过相应的算法在堆中搜索可用的足够大的空间,如果没有足够大的空间,就会调用系统函数去增加堆的空间,这样才能分配到足够大的空间,然后返回。因此堆的效率就比较低。
碎片的产生:堆的频繁new/delete势必会造成内存的不连续,从而造成大量的碎片,使程序的效率变低;但是栈不同,栈是先进后出,所以不可能有内存从栈的中间跳出,因此它的内存都是连续的,效率也就较高。
生长方向:堆是向上增长的,也就是内存地址增长的方向;栈是向下的,是往地址减小的方向。
参考http://www.cnblogs.com/hanyonglu/archive/2011/04/12/2014212.html

浙公网安备 33010602011771号