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

bas*_*hrc 1 c++ standards delete-operator c++14

我非常肯定它是,但如果我正确解释标准(第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;
}
Run Code Online (Sandbox Code Playgroud)

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

Rei*_*ica 7

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

delete[] p;
Run Code Online (Sandbox Code Playgroud)

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

::operator delete[] (p);
::operator delete(p);
Run Code Online (Sandbox Code Playgroud)

但是以下内容并不等同,因为它们不仅仅是调用释放函数:

delete[] p;
delete p;
Run Code Online (Sandbox Code Playgroud)