条款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表达式中使用[].

原创粉丝点击