条款16:成对使用new和delete时要采取相同形式
来源:互联网 发布:日本捕鲸知乎 编辑:程序博客网 时间:2024/05/22 03:34
条款16:成对使用new和delete时要采取相同形式
(Use the same form in corresponding uses of new and delete.)
内容:
我们来看下面这段简单的代码:
class Phone{...};
//test.cpp
Phone* pPhoneArray=new Phone[4];
assert(pPhoneArray != 0);
...
delete pPhoneArray;
程序运行起来的好像也良好,但却这段代码无形之中却造成了"内存泄露",你现在注意到了最后一行代码出
现了点问题:这里new出来的是4个Phone对象,而删除的时候却删除了第一个,而其它3个Phone占用的内存却没
有机会被释放掉.最后一行应该改为:delete[] pPhoneArray;为什么是这样呢?我们来作一个简单的分析一下
new和delete到底做了什么?
一个new操作执行了:(1)为该对象分配内存(调用::operator new);(2)调用构造函数初始化local成员变
量.而当你执行了一个delete操作执行了:(1)调用析构函数,释放拥有的资源;(2)释放对象所占用的memory(调
用::operator delete).这里我们的delete就遇到了一个头疼的问题:到底要删除的对象的内存有多大,是一个
对象还是多个对象,将有多少个析构函数被调用?也就是说delete的指针是执行单个对象地址还是指向一个对象
数组的?
我们先来看一下单个对象与对象数组的内存分布状态示意图:
从上面我们可以看出来,数组对象内存中包含了一个指示该数组的大小的变量size,有了这个指示我们就
能确定总共要释放的内存大小,那我们如何标识出来让编译器知道倪,我们这里采用给delete带个小标识符'[]',
这样编译器就知道了它要释放的指针原来是一个对象数组,问题解决!呵呵.
我们来举个例子:
{
...
using std::string;
string pstringMultiObject = new string[4];
...
delete[] pstringObject;
string pstringSingleObject =new string;
...
delete pstringSingleObject;
...
}
上面的代码显然现在很合理没有什么问题,如果下面两种情况发生,会出现什么情况?
(1)没有对pstringMultiObject使用"delete[]"形式.
(2)对pstringSingleObject使用"delete[]"形式.
对照内存分布示意图,先开始分析第一种情况,其结果是未有定义,由于很少的析构函数被调用.即使是内
置型类型如int(没有析构函数)也是未定义行为.第二种情况,其结果是编译器会读取单个对象的内存块当作一
个size值来看待,然后再多次size调用析构函数,浑然不知它处理的内存块压根就不是对象数组,天啊,难以想象
该操作会造成什么样的后果?
从上面的讨论我们很容易得到一个简单的游戏规则:如果你new的时候使用'[]',那么你delete的时候也请
使用'[]',反之你也不应该使用'delete []'.
在某些情况下这个规则对于typedef将显得更加重要,比如:
typedef std::string addressList[4];
std::string* paddressList=new addressList;
assert(paddressList != 0);
delete[] paddressList; //注意这里不是delete paddressList;
这里的addressList是一个含4个元素的数组类型变量,故不能使用delete paddressList;为了避免诸类错
误的发生,我们一般不使用typedef定义数组类型,代替它的是标准程序库的vector<string>类型.
好了,今天就到这里了!
请记住:
★ 如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],
一定不要在相应的delete表达式中使用[].
- 条款16:成对使用new和delete时要采取相同形式
- Effective c++ 条款16学习笔记: 成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete时要采取相同的形式
- 《Effective C++》学习笔记条款16 成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete时要采取相同形式
- Effective C++:条款16:成对使用new和delete时要采取相同形式
- Effective C++ 读书笔记 条款16:成对使用new和delete时要采取相同形式
- 条款16 成对使用new和delete时要采取相同形式
- Effective C++条款16解读:成对使用new和delete时要采取相同形式
- Effective C++条款16:成对使用new和delete时要采取相同形式
- 条款16 成对使用new和delete时要采取相同形式
- 《Effect C++》学习------条款16:成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete时要采取相同的形式
- 读书笔记《Effective C++》条款16:成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete时要采取相同形式
- 条款16:成对使用new和delete的时候要采取相同形式
- 成对使用new和delete时要采取相同形式
- 缓冲区溢出学习笔记
- log4j 详解
- 开发人员一定要加入收藏夹的网站
- 单例模式(3.注册式)
- HSGF实习第一周
- 条款16:成对使用new和delete时要采取相同形式
- C# 两个exe传递消息
- 特权级1——RPL、DPL、CPL
- 编程十诫
- 《输赢》感悟
- asp.net获取Post和Get数据的方法(Stream)
- IE浏览器无法打开网页
- Octeon - Console Connection Setting
- Flex3 设置SVN 相当实用