常量数据:常量数据区域主要用于存储字符串以及其他在编译期就已经知道值得数据。实例化的对象不能存储在这个区域。
在程序的整个生存期内,这个区域中的所有数据都有效,而且都是只读的,对这些数据进行修改的结果在C++中是没有定义的。一部分原因是编译器可能会对常量数据的基本存储格式进行任意的优化。例如,在某个特定的编译器中,可能会将字符串常量保存在重叠对象中以进行优化。
栈:在栈中存储的是自动变量。自动变量在定义时将被立即构造,并且在其作用域结束时被立即销毁,因此程序员无法对已经分配但尚未初始化的栈空间直接操作(除非你有意的使用显式析构函数和placement new的语法)。
栈内存的分配通常要比动态内存的分配(堆和自由区)快很多,因为每次栈内存的分配只涉及栈指针的自增操作,而无需复杂的内存管理。
自由存储:自由存储是两种动态内存区域之一,是通过new/delete来分配/释放的。
对象的生存期可能会小于所分配的存储空间的生存期。也就是说,自由存储区域中的对象在分配内存时,并不要求立即被初始化,而且在销毁对象时,也不要求被立即释放内存空间。在存储空间已经被分配但还没有进入对象生存期的这段时间内,虽然可以通过一个void*类型的指针来访问和操作这块存储空间,但却不能访问对象中任何一个非静态的成员变量和非静态的成员函数,不能获得它们的地址,或者进行其它的操作。
堆:堆是另一种动态内存区域,是通过malloc()/free()函数以及这些函数的其它形式来分配/释放的。
需要注意的是,尽管在某个特定编译器中,默认的全局运算符new和delete可能会用函数malloc()和free()来实现,但堆还是不同于自由存储,但堆中分配的内存不能在自由存储区中安全的释放,反之亦然。
在堆中分配的内存,可以在对象的placement new构造过程和显示的析构过程中使用。如果要这样使用,那么自由存储区域中关于对象生存期的注意事项在堆中也同样适用。
全局/静态:在程序启动时,全局变量/对象或静态变量/对象就已经分配了存储空间,但只有等到程序执行时,这些变量/对象才会进行初始化。例如,只有当程序第一次执行到变量的定义语句,函数中的静态变量才能被初始化。
对于跨越多个编译单元的全局变量,它们的初始化顺序是未定义的,因此,在管理全局对象(包括类的静态成员)之间的依赖性时要特别小心。通常来说,可以通过一个void*指针来对未初始化的对象存储空间进行访问和操作,但不能在对象的生存期之外来使用或者引用非静态的成员变量和成员函数。