10
votes

new and delete operator overloading might or might not work when compiled using different compilers and different c++ standards. Is that the normal behavior?

I used the following code to test the compilers.

#include <iostream>

void * operator new(size_t size)
{
    std::cout << "1\n";
    return malloc(size);
}

void operator delete(void *ptr) noexcept
{
    std::cout << "2\n";
    free(ptr);
}

int main(void)
{
    int *n1 = new int;
    delete n1;

    int *n2 = new int[10];
    delete[] n2;

    return 0;
}

Here are the results I got from several compilers I have tested the code on.

mingw-w64 official build - x86_64-7.1.0-release-posix-seh-rt_v5-rev0.7z

c++11
1
2

c++14
1

clang x86_64 - v4.0.0 manually built without patches using the compiler above

c++11 and c++14
1
2

msvc - platform toolset v141 & sdk v10.0.15063.0

/std:c++14 and /std:c++latest
1
2
1
2

All tests are performed on Windows 7. I can't test compilers on GNU/Linux OS because I don't have any VMs set up.

1
Where in your example does it not work? - user2672107
You need to overload the [] version(s): en.cppreference.com/w/cpp/memory/new/operator_new And the signatures have changed with standard changes, testing different compilers on different standard(s) will give different results. - Richard Critten
@RichardCritten There is no need to even overload the [] operator on the msvc compiler. See the msvc result above. - MoodyMoon
GCC 6.3 behaves the same way as msvc: ideone.com/N7wJhQ - Rosme
The mingw c++14 behavior looks a bit alarming... - aschepler

1 Answers

2
votes

By the standard, the default behavior of both operator new[] is ([new.delete.array]/4):

Returns operator new(size), or operator new(size, alignment), respectively.

Something similar goes for operator delete[] ([new.delete.array]/15):

The functions that have a size parameter forward their other parameters to the corresponding function without a size parameter. The functions that do not have a size parameter forward their parameters to the corresponding operator delete (single-object) function.

The default versions of these functions simply call the non-array forms. Therefore, Visual Studio and GCC 6.3 are correct: overloading just the non-array versions should be enough to overload the allocators.