美文网首页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++内存管理

    c++内存管理长文 c++内存管理

  • 内存管理

    内容包括: C++内存管理 Java内存管理 C++内存管理 内存分配方式 在C++中,内存分成5个区,分别是栈、...

  • Java GC

    概述 GC => 垃圾回收 = 回收可用空间 + 压缩内存 内存管理 手动内存管理 => C | C++ 自动内存...

  • C++之内存布局

    在C++之内存管理一文中,我们已经了解到C++的内存管理,这里介绍C++的典型内存布局结构。 1、总体来说,C/C...

  • C++ 内存分配和管理

    C++ 内存分配和管理

  • Java内存泄漏

    本文将会介绍: C++中的内存泄露 Java内存管理与垃圾回收 Java中的内存泄漏 一、C++中的内存泄露 在大...

  • 编程语言介绍

    Java:跨平台,自动内存管理; python: ; c:; c++:Essential C++,C++Prime...

  • android 内存泄漏全面解析

    引言: C/C++ 自己去分配内存和释放内存--手动管理 malloc free 什么是内存泄露:内存不在GC掌...

  • 第二章 Java内存区域和内存溢出异常

    概述 java内存管理相比于C和C++自己管理内存方便了很多,不用自己手动去管理和释放内存,不必为每一个对象...

  • 19. java虚拟机总结-JVM 内存管理 (三)

    JVM 内存区域划分 1.为什么进行内存区域划分? Java自动内存管理机制是它和C++的区别所在。C++是手动内...

网友评论

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

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