在Visual C ++中删除和删除[]相同?

时间:2008-11-19 09:14:25

标签: c++ visual-c++

我知道在使用delete []后我应该使用new [],因此将auto_ptrnew []一起使用并不是一个好主意。

但是,在调试delete []时(使用Visual Studio 2005),我注意到调用进入了一个看起来像这样的函数:

void operator delete[]( void * p )
{
    RTCCALLBACK(_RTC_Free_hook, (p, 0))
    operator delete(p);
}

这是否意味着,Visual C ++上的[]语法丢失了?如果是这样,为什么?是否可以减轻开发人员记住正确语法的负担?

5 个答案:

答案 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 newoperator delete(以及它们的不同风格)周围会出现一些编译器魔法,基本上是在幕后添加对ctors和dtors的调用。这种魔法取决于那些小括号[],所以不要丢失它们,否则你将失去魔力。

答案 1 :(得分:4)

我想这只是一个实现细节。它们的堆分配器在释放数组和指针时的工作方式相同。

但由于该标准允许实现针对这两种情况使用不同的算法,因此您不应该假设deletedelete[]执行相同的操作。这种行为甚至可能在编译器版本之间发生变化。

答案 2 :(得分:2)

仅仅因为他们现在可能会一样工作,并不意味着你必须对待他们 - 行为可能会改变。此外,谁在乎 - 你应该编写代码,这样你就不必记住了。

此外,您可以使用scoped_array删除数组。

答案 3 :(得分:2)

您删除的数据可能没有析构函数?如果是这样,这个简单的删除就有意义了。毕竟它正在研究无效*。

无论如何,你应该使用delete []来确保为数组中的每个元素运行析构函数。

答案 4 :(得分:2)

删除不带[]的数组只会释放内存,但不会调用数组中每个对象的析构函数。因此,从技术上讲,如果需要调用析构函数,则只需要[]。