成对使用 new 和 delete 时要采取相同形式
先看下面两行代码有什么错:
std::string* stringArray = new std::string[100];
...
delete stringArray;
看起来似乎还好,使用了 new 的同时在最后也使用了 delete,但还是有个致命的错误:程序行为不明确(未有定义)。最低限度,stringArray 所含的 100 个 string 对象中的 99 个不太可能被删除,因为它们的析构函数很可能没被调用。
解释:
当你使用 new(也就是通过 new 动态生成一个对象)时,有两件事会发生。第一,内存被分配出来(通过名为 operator new 的函数,见条款 49 和 条款 51)。第二,针对此内存会有一个(或更多)构造函数被调用。
当你使用 delete 时, 也有两件事发生。第一,针对此内存会有一个(或更多)析构函数被调用,然后内存才被释放(通过名为 operator delete 的函数,见条款 51)。
delete 的最大问题在于:即将被删除的内存之内究竟存有多少个对象?这个问题的答案决定了有多少个析构函数必须被调用起来。
其实解决这个问题的方法很简单,只需看动态分配内存的指针指向的是单一对象还是对象数组就可以了。
std::string* stringPtr1 = new std::string;
std::string* stringPtr2 = new std::string[100];
...
delete stringPtr1; // 删除一个对象
delete []stringPtr2; // 删除一个由对象组成的数组
请记住:
- 如果调用 new 时使用了 [ ],也就必须在对应调用 delete 时也使用 [ ]。如果调用 new 时没有使用 [ ],也不应该在对应调用 delete 时使用 [ ]。