GotW #9: 内存管理 上部

原文:http://www.gotw.ca/gotw/009.htm
看过Exceptional C++的可以跳过。

难度:3/10
本节包括了C++的主要内存使用的基础。有些问题引发了内存管理的大讨论。

问题:
C++有几种独特的内存区域,存储了对象和非对象值,每个区域都有特殊的功能和参数。
说出它们的名字,并详细说出它们的性能参数,描述其中存储的元素的生命期。
例子:栈存储自动变量,包括内部类型和类对象。

答案:
以下总结了C++程序的主要的独特内存区域,注意有些名字(比如堆)在标准中没有出现。
常量数据:
const数据区域存储了字符串常量和其他在编译期即确定其值的数据。类对象不在这区域中。这里的数据在程序运行的生命期里都有效。这里所有的数据都是只读的,试图修改它们值的行为是未定义的,部分原因是其中的数据格式会根据具体实现而随机优化。比如,有的编译器可能把字符串常量重叠存储。
栈:
栈存储了自动变量,栈的空间分配要比动态分配(堆或自由存储)快的多,因为栈的分配只需要修改指针,不用做复杂的操作。内存分配之后对象立刻构造完成,销毁之后立刻回收空间。所以程序员不可能去直接使用已经分配好但尚未初始化的栈空间,除非故意用放置new或显式的析构函数捣乱。
自由存储:
自由存储是两种动态内存区域之一,使用new/delete来分配与回收空间。对象的生存期比空间分配好的时间短;就是说,自由存储中的对象可以在内存分配后不立刻初始化,可以销毁对象后不立即回收空间。在空间已分配却不在对象的生存期的时候,程序员能通过void*来访问这段空间,但是不能访问原始对象的非static成员或成员函数(即使知道它们的地址)。
堆:
另一种动态分配区域,通过malloc和free来分配和回收内存。注意到当默认的全局new和delete是用malloc和free来实现的情况下,堆和自由存储仍然是不一样的,而且一者的空间不能由另一者释放。类对象能够使用放置new构造和显式析构来使用堆里的空间。此时,生存期和自由存储的相同。
全局/静态:
全局或静态的变量或对象的空间在程序启动时就已经分配完成,但可能要等到程序开始执行才初始化。例如:函数内的一个静态变量在程序执行过它的定义后才初始化。全局变量的初始化顺序是未定义的,全局变量(包括类内的静态成员)的依赖关系是尤其要小心的。通常,未初始化的原始对象的空间可以用void*来访问。但在类对象的实际生存期外,则不能使用或引用非静态成员或成员函数。

关于堆和自由存储:在这里把两者区分开来,是由于C++标准草案里没有表明两者是否有关联。比如通过delete释放内存时,18.4.1.1说:It is unspecified under what conditions part or all of such reclaimed storage is allocated by a subsequent call to operator new or any of calloc, malloc, or realloc, declared in <cstdlib>.
()
同样,new和delete是用malloc/free实现还是其他方法也是未指定的。记住,这两类的使用方法是不一样的,空间访问也是不一样的。所以,区别对待这两者。

posted on 2012-02-22 22:42 高兴 阅读(263) 评论(0)  编辑 收藏 引用 所属分类: GotW


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜