美文网首页C++
C++之内存管理

C++之内存管理

作者: wenmingxing | 来源:发表于2018-05-24 15:52 被阅读41次

    本文主要说明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++内存管理详解

    相关文章

      网友评论

        本文标题:C++之内存管理

        本文链接:https://www.haomeiwen.com/subject/hgbrjftx.html