Search code examples
c++standardsc++14delete-operator

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


I am pretty much sure it is but if I am interpreting correctly the standard (Section 18.6.1.2 new.delete.array) mentions that:

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

. 13 Default behavior: Calls operator delete(ptr)

Since in its default behavior delete[] just calls its delete(ptr) equivalent why should it matter which version is called? I tried with a sample code to verify this and it crashes making it more evident that mismatching new[] and delete indeed lead to bad things

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

How should the above quoted line from the standard be interpreted?


Solution

  • You're confusing the delete[] expression with the function operator delete[]. When you write:

    delete[] p;
    

    then the compiler issues code which will call destructors for all objects in the array pointed to by p, and then call the deallocation function operator delete[] with the argument p. As per the documentation you've quoted, the default ::operator delete[] calls ::operator delete. So the following calls to the deallocation functions are equivalent when default implementations are used:

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

    But the following are not equivalent, because they do much more than just call the deallocation functions:

    delete[] p;
    delete p;