Al compilar con MINGW gcc, no se llama al nuevo operador sobrecargado para std :: string


8

Este programa (compilado con la opción -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;
}

Cuando se compila con Clang o MSVS, imprime:

asignar 4 bytes en el montón

asignar 2016 bytes en el montón

Sin embargo, cuando se compila con GCC (Versión 9.2.0 proporcionada por MSYS en Windows) solo imprime:

asignar 4 bytes en el montón

Soy consciente de la optimización de cadenas cortas en GCC / libc ++, pero ¿no son 2000 caracteres demasiado para una cadena corta? ¿Es una cuestión de SSO?


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Samuel Liew

Respuestas:


4

Parece que GCC no implementa (o no puede) la sustitución de la global operator newy operator deletecorrectamente cuando las bibliotecas dinámicas están involucradas en Windows.

Ver informes de errores, por ejemplo, 77726 , 82122 y 81413 .

En su caso std::string, el constructor y / o std::allocator<char>::allocateparece estar ubicado en la biblioteca dinámica de la biblioteca estándar, de modo que el operator newque utiliza no se está reemplazando correctamente.


1
Para aclarar más: este comportamiento solo se ha observado cuando se usa GCC con libc ++ en Windows proporcionado por MSYS / MINGW. Cada versión de GCC / libstdc ++ en Ubuntu que pude probar funcionó exactamente como los programas compilados con Clang o MSVS. Además, claramente no es un caso de SSO cuando se compila con GCC, como sizeof(str)rendimiento 32.
Angle.Bracket

@ Angle.Bracket ¿Te refieres a libstdc ++ en lugar de libc ++?
nogal

Supongo que se llama libc ++ en MINGW
Angle.Bracket

@ Angle.Bracket libc ++ generalmente se refiere a la implementación estándar de la biblioteca del proyecto LLVM para clang. No creo que gcc pueda usarlo, mingw o no. Pero puedo estar equivocado aquí.
nogal

@ Angle.Bracket Supongo que puede verificar si está usando libstdc ++ o libc ++ usando las respuestas en esta pregunta .
nogal
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.