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

Is calling delete operator on a memory allocated by new[] operator undefined behavior?

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

void operator delete[](void* ptr) noexcept; pointer.

. 13 Default behavior: Calls operator delete(ptr)

既然在默认行为中 delete[] 只是调用它的 delete(ptr) 等价物,为什么调用哪个版本很重要? 我尝试使用示例代码来验证这一点,但它崩溃了,这使得 new[] 和 delete 不匹配确实导致了不好的事情变得更加明显

#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;
}

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

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

delete[] p;

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

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

但是以下 不是 等价的,因为它们所做的不仅仅是调用释放函数:

delete[] p;
delete p;