C++中的堆和栈

在C++中,内存分为5个区:堆、栈、自由存储区、静态存储区(或全局存储区)和常量存储区。
堆和栈都是C++的内存存储区之一,下面介绍堆和栈对比用法:

1.管理方式和分配效率:

是机器系统提供的数据结构,是FILO(First In Last Out)结构,计算机底层对它进行了支持,栈的内存分配内置于处理器的指令集(分配了专门的寄存器存放栈的地址,压栈和出栈都有专门的指令),这也就决定了栈的分配效率较高。
是由C/C++函数库提供的,由一套复杂的算法实现。堆中有一个记录空闲内存地址的链表,当系统收到进程的空间申请时,根据使用的分配算法找到合适的地址空间。(比如first-fit算法:遍历此链表,找到第一个空间大于申请大小的空闲内存分配给进程,从空闲链表中将此节点删除,并记录此次分配的大小,添加到已分配内存链表中,另外将多余的空闲空间添加到空闲链表中,将分配内存的首地址返回给进程使用)此后进程可以合理地使用这块空间,有时由于申请的空间太大,空闲链表中找不到合适的内存,系统会使用mmap扩展有效堆内存,以获得更多的虚拟地址空间。基于以上,堆的申请效率较低。

2.空间特点:

的空间较小,windows下栈的大小是一个在编译时就确定的常量,通常是1M或2M,在unbutu下一般是8M,Centos下是10M,可以通过ulimit -a查看,ulimit -s进行修改。
栈是一块连续的空间,每次申请也是申请连续的大小。
的空间较大,一般和系统有关,32位系统堆大小一般为4G。
堆是由空闲内存地址链表管理,堆空间是不连续的申请,每次申请都是在空闲空间链表上找合适大小的空闲空间进行分配。

3.内存碎片:

由于栈是系统进行分配和释放,而且由于栈这种数据结构的特点FILO,不会出现间隔的分配,所以栈不会有产生内存碎片,而堆是由程序员手动进行分配和释放,存在碎片。

4.分配方式:

栈是由系统分配和释放,当申请的空间小于剩余的空间则进行分配,否则抛出stack overflow。
栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配(alloca不具可移植性, 而且在没有传统堆栈的机器上很难实现),用完由编译器自动释放,如果手动释放会出错。
alloca的函数具体用法:
头文件: malloc.h
函数原型:void * __cdecl alloca(size_t);

#include 
#include 
int main()
{	
	int *p = (int *)alloca(sizeof(int)*10);
	free(p); //error,空间在栈中,手动释放是报错
	return 0;
}

堆是由程序员自己进行申请和释放,使用new和malloc等申请,对应的由delete和free进行释放。使用灵活,但容易发生内存泄露(memory leak)申请的空间可以很大。在项目很大时,难免发生内存泄露。较好的选择是重载new和delete,跟踪定位程序发生内存泄露的地方。

5.生长方向:

栈的生长方向是向下生长,即由内存高地址向低地址生长。
堆的生长方向是向上生长,由内存的低地址向高地址生长。
堆和栈之间由一层临界区,大小可以进行修改,如果栈的空间到达临界区,则会提示stack overflow。

你可能感兴趣的:(C++内存管理,C++,堆和栈)