当编译一个C++程序时,计算机的内存被分成了4个区域,一个包括程序的代码,一个包括所有的全局变量,一个是堆栈,还有一个是堆(heap),我们称堆是自由的内存区域,我们可以通过new和delete把对象放在这个区域。
内存管理
系统为每个程序建立一虚拟的内存空间,这一空间可以分为划分为三个区域:1)代码与数据区。用于存放程序代码和预先需要分配空间的数据(如全局变量、静态变量)叫静态存储区;2)栈区。由系统保留使用,组织的方式和栈一样,遵循后进先出的规则。用语存放程序的临时状态数据,如进行函数调用时存放返回地址、传递的参数以及局部变量等,这些空间在退出函数作用域时将会释放。3)堆,也称自由存储区。程序运行期间由程序员动态申请的空间在堆中分配。如用new或malloc分配的空间。这些空间需要程序员显式地用delete或free释放并归还给堆。
从C++语言的角度来看,C++中的对象/变量按照存储类型来分,可以分为三种:
1)静态存储区
静态变量被分配在此区段,全局变量隐含的是静态的。变量的分配是编译和链接时完成的,但是初始化直到程序中的定义语句处才进行,如果定义时没有提供初始化表达式,则使用默认值初始化。直到程序结束之前,变量不会被销毁。
2)栈区
非静态局部变量分配在程序的栈(stack)中,他们程序执行到作用域(scope)的开始处分配空间并且初始化(如果有的话),在离开作用域之前被销毁。因此,变量的创建和销毁是自动完成的,又叫做自动(automatic)变量,你可以在自动变量前使用auto关键字,但是不会产生额外的效果。
3)自由存储区
使用new创建的变量分配在自由存储区(free store),变量的创建和销毁由程序完全的控制,一般使用运行环境(操作系统)提供的功能调用接口完成。
存在另一种观点,认为还有两种类型:
1)常量区
字面常量存放在该区域,更改此区域的内容的行为其结果不可预期。然而,概念上,字面常量的区域和静态存储区的特点是类似的,附加的只读保护功能是实现相关的,例如8086实模式下没有数据段的只读保护功能,因此该模式下的程序不可能严格区分常量区和静态存储区。
2)堆
实在难以理解堆(heap)和自由存储区(free store)的区别,仔细阅读持这种意见的文章,似乎唯一说得通是heap是malloc/free使用的,而free store是new/delete使用的,由于C++标准并没有规定new/delete一定用malloc/free实现,因而从这个角度上来看,堆和自由存储区物理上可能是不相同的。然而,从行为特征上来看,二者并没有本质的区别,仅仅是因为实现的差异而已。
[C++标准]
C++标准中使用了前面三种存储区间的说法,正式的名称对应为Static Storage Duration(静态存储区间),Automatic Storage Duration(自动存储区间),Dynamic Storage Duration(动态存储区间)。