Effective C++ 学习笔记 《十六》

    xiaoxiao2025-03-22  22

    Item 16 Use the same form in corresponding uses of new and delete

    Item16讲的点其实就是关于delete在处理数组和单个对象时需要注意的地方,总结成一句话就是: if you use [] in a new expression, you must use [] in the corresponding delete expression. If you don’t use [] in a new expression, don’t use [] in the matching delete expression。 (如果你在new的时候用到了[]运算符,那么在delete的时候务必也用上,反之亦反)

    书上首先说了一下new 和 delete的过程

    new动态生成对象的过程:

    分配内存一个或多个构造函数被调用

    delete释放对象的过程:

    一个或多个析构函数调用释放内存

    问题就在于对于new得到的一个指针,delete如何判断出即将被释放的内存空间有多少个对象 因为单一对象的内存布局和数组的内存布局一般不同,比如 书上给的例子是说有的数组结构中会存一下大小n 但是单一对象就没有这个成分了

    而且最重要的是当你对一个指针用delete,唯一让delete知道释放的是数组还是单一对象的方法就是让你来告诉他 如果你写的是delete[],那么delete就认为这个指针指向的是一个数组,如果没写,就是单一对象。

    比如下面这段代码,stringPtr1 指向一个string, stringPtr2指向一个string 数组 ,所以对应的delete ptr1不写[], delete ptr2写[]

    std::string *stringPtr1 = new std::string; std::string *stringPtr2 = new std::string[100]; ... delete stringPtr1; // delete an object delete [] stringPtr2; // delete an array of objects

    书上接着说对于这两种情况,如果采取错误的delete方式,都是未定义的行为。 比如 对单一对象使用delete[] ,如果是像前面所说数组有成分保存数组长度n,那么这个delete就会尝试解释若干内存为数组大小,然后多次调用析构函数,很明显这样的结果是未定义的 又比如对数组使用delete,那么只会对数组首元素调用析构函数,所以这种结果也是未定义的。

    最后书上还强调了typedef中的注意点,比如

    typedef std::string AddressLines[4]; std::string *pal = new AddressLines;

    这里把一个大小为4的string数组定义为AddressLines,所以这个指针pal指向的是一个数组,那么对应的delete形式就应该是delete [] pal; 但是光从AddressLines字面上我们很难分辨这是一个数组还是单一对象,从而影响我们决定使用哪种类型的delete,所以书上给出的建议就是不要对数组形式做typedef,那怎么来解决这种需求呢?当然是可以使用STL,写成vector< string > 就好啦,这样它的内存释放工作就交给vector的析构函数来解决从而避免了错误。

    最新回复(0)