C++

C++之内存管理

2018-05-24  本文已影响41人  wenmingxing

本文主要说明C++的内存管理。

对于C++的内存结构,主要有两种说法,一个是{栈区,堆区,全局区(静态区), 常量区,代码区}。另一种说法为{栈区,堆区,全局区(静态区), 自由存储区}。

在第二种说法中,增加了自由存储区,其与堆区没有本质区别,只是new分配的存储在堆区,malloc分配的存储在自由存储区。所以我们重点看第一种说法。

I、栈区

1、在函数中,函数的局部变量的存储单元在上,函数执行结束后栈区自动释放。

2、栈内存分配效率高,由操作系统和编译器自动分配,但存储空间有限。

II、堆区

1、堆区中的内存由程序员自己创建并维护,每个new都应该对应于一个delete,如果程序员忘记释放堆内存,则在程序最后结束后会由操作系统完成释放,但在程序运行过程中可能会造成堆区越来越大,从而造成内存溢出

2、 明确区分栈与堆

理解这个问题最好的办法就是下面的例子:

void f() {
    int *p = new int[5];
}

在上面的例子中,p存储在栈区,因为其是函数的局部变量,而p指向的空间(是一个存储int的数组)则存储在堆区。

III、全局区(静态区)

1、这部分内存区存储程序的全局变量和静态变量,其中关于静态变量的详细内容可以参见:C++ 小探static关键字

IV、常量区

1、常量区内存空间存储常量(包括字符串,等内容),如下面示例:

char *p = "123456";    

其中指针p存储在栈区,而123456存储在常量区。

V、代码区

1、代码区存放函数体的二进制代码。

VI、栈vs堆

1、管理方式不同;

2、空间大小不同:栈的大小一般是以MB为单位的。

3、能否产生碎片不同:由于管理方式的不同,所以堆更容易产生碎片。这是由于频繁的调用new/delete而造成内存空间不连续。而对于栈,其由操作系统管理,每次弹出的内存块意味着它上面的内存块也已经弹出,所以几乎不会产生碎片。

4、生长方式不同:堆的生长方向是向上的,也就是向着内存地址增加的方向;而对于栈,其的生长放下是向下的,向着内存地址减小的方向生长。

5、分配方式不同:堆是动态分配的;而栈其实具有两种分配方式,在栈的静态分配中是由编译器完成的,如局部变量的分配;动态分配的栈是由函数 alloca完成的,虽然是动态分配的栈,但是我们也无需对其进行手工释放,也是由操作系统完成的。

6、分配效率不同: 栈是及其系统提供的数据结构,计算机对其底层提供支持,有专门的寄存器存放栈的地址,并有专门的指令执行push/pop等操作。而堆是由库函数提供的,其机制很复杂。

【参考】
[1] C/C++内存管理详解

上一篇 下一篇

猜你喜欢

热点阅读