释放对象数组:delete与delete[]
<c++ primer>练习 14.11
在 <c++ primer>
练习 14.11 中提到:
Account *parray = new Account[100];
delete parray;
delete [] parray;
方括号的存在会使编译器获取数组大小(size)然后析构函数再被依次应用在每个元素上,一共 size 次。否则,只有一个元素被析构。无论哪种情况,分配的全部空间被返还给自由存储区。
我有问题:为什么无论哪种情况,分配的全部空间被返还给自由存储区?对于 delete parray
, 为什么不是删除单个 Account
元素,而是删除了 100 个.编译器怎么知道 parray
这个指针实际指向的是数组还是单个元素,即便知道指向的是自由存储区的数组,这个数组的大小又怎么知道。难道是编译器辅助行为?
总结:空间释放(肯定有个log记录分配的大小)和调用析构函数(类型识别,不同的编译器不同)。
转自 <effective c++>
条款5:对应的 new
和 delete
要采用相同的形式
下面的语句有什么错?
string *stringarray = new string[100];
delete stringarray;
一切好象都井然有序——一个 new
对应着一个 delete
——然而却隐藏着很大的错误:程序的运行情况将是不可预测的。至少,stringarray
指向的 100 个 string
对象中的 99 个不会被正确地摧毁,因为他们的析构函数永远不会被调用。
用 new
的时候会发生两件事。首先,内存被分配(通过 operator new
函数,详见条款7-10和条款m8),然后,为被分配的内存调用一个或多个构造函数。用 delete
的时候,也有两件事发生:首先,为将被释放的内存调用一个或多个析构函数,然后,释放内存(通过 operator delete
函数,详见条款8和m8)。对于 delete
来说会有这样一个重要的问题:内存中有多少个对象要被删除?答案决定了将有多少个析构函数会被调用。
这个问题简单来说就是:要被删除的指针指向的是单个对象呢,还是对象数组?这只有你来告诉 delete
。如果你在用 delete
时没用括号,delete
就会认为指向的是单个对象,否则,它就会认为指向的是一个数组:
string *stringptr1 = new string;
string *stringptr2 = new string[100];
...
delete stringptr1; // 删除一个对象
delete [] stringptr2; // 删除对象数组
如果你在 stringptr1
前加了 "[]" 会怎样呢?答案是:那将是不可预测的;
如果你没在 stringptr2
前没加上 "[]" 又会怎样呢?答案也是:不可预测。对 int
这样的固定类型来说,结果也是不可预测的,即使这样的类型没有析构函数。所以,解决这类问题的规则很简单:如果你调用 new
时用了 "[]", 调用 delete
时也要用 "[]"。如果调用 new
时没有用 "[]", 那调用 delete
时也不要用 "[]".