C++内存管理与分配方式

C++的内存管理与内存分配方式,实际上是两个问题。

C++程序在编译与运行过程中,实际上可能用到五种存储区域。

  1. 栈(stack)。函数运行过程中创建的局部变量都存储在栈上。随着函数或代码块的运行结束,这些局部变量的空间也会被自动回收。栈的优点是栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  2. 堆(heap)。也成为动态存储区。使用new,malloc操作可以动态地分配这部分内存。优点是动态存储区的内存分配和回收都由程序员决定,缺点是如果忘记回收,可能造成内存泄漏,并且分配次数过多可能产生堆碎片。
  3. 全局区或静态区 --存放全局变量和静态变量;程序结束时由系统释放,分为全局初始化区和全局未初始化区;
  4. 字符常量区 --常量字符串放与此,程序结束时由系统释放;
  5. 程序代码区--存放函数体的二进制代码

 

为什么这里没有提到自由存储区?

因为自由存储区和这里提到的五种存储区是两个维度的概念,针对这个问题我们一点一点来分析。

自由存储区和堆往往是容易混淆的地方。因为我们知道,C提供了malloc/free这对函数来提供动态内存的申请和释放。而malloc函数申请的内存位置在堆上。C++在继承了C语言的malloc/free的基础上,还提供了new/delete这对保留字来提供更加便捷的动态内存申请与释放。

malloc函数只分配空间,不调用任何构造函数,返回的是指向分配到的空间的void型的指针,如果失败了就返回NULL指针。

而new不仅申请动态空间,同时会调用该类型变量的构造函数。如果分配成功会返回该类型的指针,失败了会返回bad_alloc异常。

而这两个函数申请的动态空间位置的定义,是最令人混淆的地方。malloc函数明确说明,分配的位置在堆上,这点没有异议。而new分配的位置,按照Bjarne Stroustrup的说法,是在free store(自由存储区)上。那么,自由存储区就是堆吗?还是C++另外开辟的一块内存空间?

实际上,C++的实际内存空间如上所述,只有这五种,而自由存储区,是一种抽象的概念,而不是内存中的实际区域。可以这样认为:自由存储区就是new分配的区域。而自由存储区的底层,具体的内存空间,还应当是上述五种空间之一。因为C++的默认new是使用malloc实现的,所以大多情况下,自由存储区都建立在堆的基础上。但是,如果对new进行重载,则可以使用其他区域实现自由存储区。

 

而在分配内存时,有三种方式

  1. 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
  2. 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  3. 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。
    动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它。
posted @ 2019-03-22 23:10  sleepygod  阅读(756)  评论(0编辑  收藏  举报