在C和C++中,有三种使用存储区的基本方式:
[静态存储区(Static Memory)]
在静态存储区中,连接器(linker)根据程序的需求为对象分配空间。全局变量、静态类成员以及函数中的静态变量都被分配在该区域中。一个在该区域中分配的对象只被构造一次,其生存期一直维持到程序结束。在程序运行的时候其中的地址是固定不变的。在使用线程(thread,共享地址空间的并发物)的程序里,静态对象可能会引起一些问题,因为这时的静态对象是被共享的,要对其正常访问就需要进行锁定操作。
[自动存储区(Automatic Memory)]
函数的参数和局部变量被分配在此。对同一个函数或区块的每一处调用,其在该区域内都有自己单独的位置。这种存储被自动创建和销毁;因而才叫做“自动存储区”。自动存储区也被称为是“在栈上的(be on the stack)”。
[*存储区(Free Store)]
在该区域中,程序必须明确的为对象申请空间,并可以在使用完毕之后释放申请到的空间(使用new和delete运算符)。当程序需要其中更多的空间时,就使用new向操作系统提出申请。通常情况下,*存储区(也被称作动态存储区或者堆(heap))在一个程序的生存期内是不断增大的,因为其间被其它程序占用的空间从来都不被归还给操作系统。例如:
int g = 7; //全局变量,分配在静态存储区中
void f()
{
int loc = 9; //局部变量,分配在栈(stack)中
int* p = new int; //变量被分配在*存储区中
// …
delete p; //归还p所指向的区域,以便重新使用
}
对程序员来说,自动存储区和静态存储区总是被隐式的使用,这种方式既简单又一目了然。真正有趣的问题是应该如何管理*存储区。分配空间(使用new运算符)是很简单的,但在去配的时候,则必须有一个完善的归还空间的方案;否则的话,存储空间最终会被耗尽(特别是在长时间运行的程序中)。
对于这个问题,最简单的解决方案就是使用与*存储区中的对象相对应的自动对象来处理分配和去配。基于此,许多container在实现的时候,都被作为*存储区中对象的掌控者(handle)。