c++gccstdstringgcc9

When compiling with MINGW gcc, overloaded new operator is not called for std::string


This program (compiled with option -std=c++17)

#include <stdio.h>
#include <string>
void* operator new(std::size_t nrOfBytes) {
    printf("allocate %zd bytes on heap\n", nrOfBytes);
    void* p = malloc(nrOfBytes);
    if (p) {
        return p;
    } else {
       throw std::bad_alloc{};
    }
}
int main() {
    // new operator is called when compiled with Clang or MSVS or GCC 
    int* i = new int;
    delete i;
    // new operator is not called when compiled with GCC
    // but is called with Clang and MSVS 
    std::string str(2000, 'x');
    return 0;
}

when compiled with Clang or MSVS, prints:

allocate 4 bytes on heap

allocate 2016 bytes on heap

However, when compiled with GCC (Version 9.2.0 provided by MSYS on Windows) it only prints:

allocate 4 bytes on heap

I am aware of short string optimization in GCC/libc++, but aren't 2000 chars too many for a short string? Is it a matter of SSO at all?


Solution

  • It seems that GCC does not (or can't?) implement replacement of the global operator new and operator delete correctly when dynamic libraries are involved on Windows.

    See bug reports e.g. 77726, 82122 and 81413.

    In your case std::string's constructor and/or std::allocator<char>::allocate seem to be located in the standard library's dynamic library, so that the operator new it uses isn't being replaced correctly.