是否在由new []操作符未定义行为分配的内存上调用delete运算符?

时间:2015-05-06 08:39:51

标签: c++ standards c++14 delete-operator

我非常肯定它是,但如果我正确解释标准(第18.6.1.2节new.delete.array)提到:

  

void operator delete [](void * ptr)noexcept;   指针。

     

13默认行为:调用operator delete(ptr)

因为在默认行为中delete []只是调用它的delete(ptr)等价物,为什么调用哪个版本有关系? 我尝试使用示例代码来验证这一点并且崩溃使得更明显的是不匹配的新[]和删除确实导致了不好的事情

#include <iostream>
#include <memory>
class foo{
    public:
        void bar(){
            std::cout << "foo's bar" << std::endl;
        }
        ~foo(){
            std::cout << "foo dies after this" << std::endl;
        }
};
int main() {
    std::shared_ptr<foo> x(new foo[10]);
    return 0;
}

如何解释标准中的上述引用行?

1 个答案:

答案 0 :(得分:7)

您将delete[]表达式与函数operator delete[]混淆。当你写:

delete[] p;

然后编译器发出代码,该代码将为p指向的数组中的所有对象调用析构函数,然后使用参数operator delete[]调用释放函数p。根据您引用的文档,默认::operator delete[]调用::operator delete。因此,当使用默认实现时,以下对释放函数的调用是等效的:

::operator delete[] (p);
::operator delete(p);

但以下是等效,因为它们不仅仅是调用释放函数:

delete[] p;
delete p;