我知道在使用delete []
后我应该使用new []
,因此将auto_ptr
与new []
一起使用并不是一个好主意。
但是,在调试delete []
时(使用Visual Studio 2005),我注意到调用进入了一个看起来像这样的函数:
void operator delete[]( void * p )
{
RTCCALLBACK(_RTC_Free_hook, (p, 0))
operator delete(p);
}
这是否意味着,Visual C ++上的[]
语法丢失了?如果是这样,为什么?是否可以减轻开发人员记住正确语法的负担?
答案 0 :(得分:26)
考虑以下代码:
class DeleteMe
{
public:
~DeleteMe()
{
std::cout << "Thanks mate, I'm gone!\n";
}
};
int main()
{
DeleteMe *arr = new DeleteMe[5];
delete arr;
return 0;
}
如果你在VS2005中运行它,它将打印:
Thanks mate, I'm gone!
如果您更改main()
以正确遵守C ++标准:
int main()
{
DeleteMe *arr = new DeleteMe[5];
delete[] arr;
return 0;
}
它将打印:
Thanks mate, I'm gone! Thanks mate, I'm gone! Thanks mate, I'm gone! Thanks mate, I'm gone! Thanks mate, I'm gone!
不要用脚射击自己。如果不匹配不同的新/删除风格,VS2005将不做正确的事情。任何其他C ++标准都不符合编译器。
在operator new
和operator delete
(以及它们的不同风格)周围会出现一些编译器魔法,基本上是在幕后添加对ctors和dtors的调用。这种魔法取决于那些小括号[],所以不要丢失它们,否则你将失去魔力。
答案 1 :(得分:4)
我想这只是一个实现细节。它们的堆分配器在释放数组和指针时的工作方式相同。
但由于该标准允许实现针对这两种情况使用不同的算法,因此您不应该假设delete
和delete[]
执行相同的操作。这种行为甚至可能在编译器版本之间发生变化。
答案 2 :(得分:2)
仅仅因为他们现在可能会一样工作,并不意味着你必须对待他们 - 行为可能会改变。此外,谁在乎 - 你应该编写代码,这样你就不必记住了。
此外,您可以使用scoped_array删除数组。
答案 3 :(得分:2)
您删除的数据可能没有析构函数?如果是这样,这个简单的删除就有意义了。毕竟它正在研究无效*。
无论如何,你应该使用delete []来确保为数组中的每个元素运行析构函数。
答案 4 :(得分:2)
删除不带[]的数组只会释放内存,但不会调用数组中每个对象的析构函数。因此,从技术上讲,如果需要调用析构函数,则只需要[]。