Should I use delete or delete[] when receiving either a dynamic array or heap object?
假设我在堆上有两个项目:
1 2 | Foo *f = new Foo; Foo *g = new Foo[42]; |
并说我有一个接收
1 2 3 4 | void bar(Foo *p) { // some stuff delete p; } |
可以这样调用该函数:
1 2 | bar(f); // passing a pointer to a Foo object on the heap bar(g); // passing a pointer to an array on the heap |
我认识到应该分别使用
听起来您对"单一责任原则"有疑问。
您需要对单个对象进行一定数量的处理,因此传递单个对象或数组是合理的。 (为什么该处理对除第一个对象或非动态对象之外的数组元素也没有用?)
然后,您必须释放该对象。或数组。
这里有三个不同的任务,需要三个不同的功能。
本质上,如果"该函数不知道其参数
同样,一旦处理移到一个单独的函数,就很容易制作一个函数,"处理然后删除单个对象"以及"处理然后删除数组"而无需重复(都为处理组件调用辅助函数)。
您无法(方便地)检测到该错误并在函数中执行正确的操作。
一种"解决方法"是使用
解决方案1.从代码设计的角度来看,您可能应该完全避免这种情况,并用同一类,一对创建破坏函数或分配该对象的代码块删除该对象。这样,您就知道自己没有犯任何错误。
解决方案2。如果编译器支持它们,请使用
1 2 | std::shared_ptr<Foo> f(new Foo[20], [](Foo* p) { delete[] p; }); std::shared_ptr<Foo> g(new Foo); |
第一个
默认情况下,
你不能您永远不会知道指针是指向一个对象还是该对象的数组。
但是,如果您确实要有一个用于释放的函数,并且即使您曾经分配一个对象,也曾经记得分配类似于数组的任何东西,则以下用法合法:
1 2 3 4 5 6 7 8 | Foo *h = new Foo[0]; Foo *f = new Foo[1]; Foo *g = new Foo[42]; void bar(Foo *p) { // some stuff delete [] p; } |
但是,请记住,有时技术上可能并不意味着您应该使用它。这取决于您的用例,将对象视为数组的特例是否有意义。
更为优雅的C ++方法是使用
您必须通过它是。该函数无法在运行时
请参阅此处以获得良好的解释。
由编译器供应商决定应如何实现,因此属于"魔术"类别。
通常,运行时将在使用new []时额外分配4个字节。然后它将在这些字节中存储数组的大小,并返回分配+ 4个字节。取消分配时,它将从传递给它的指针中删除4,读取大小并使用该值确定要调用的析构函数等。
您可以在C ++常见问题中阅读有关此内容的更多信息。