2011-11-18 9 views
47

Primero, hubo al menos 4-5 temas con un tema similar en SO. Leo cada uno de ellos y no creo que realmente me ayuden con este tema específico. Si alguien más encuentra una pregunta duplicada, me disculpo. He hecho mi parte de búsqueda antes de publicar esto, ya que parece ser una pregunta muy común.Cómo reemplazar correctamente los operadores globales nuevos y eliminar

Estoy utilizando Visual Studio .NET 2003 en Windows 7.

tengo mis propias sobrecargas de nueva/borrar ese punto de mi propia costumbre llamadas a malloc() y free() para el diagnóstico. Mis nuevas/borrar sobrecargas están en un archivo de encabezado que he incluido en algunos archivos.

El problema es que la base de código es más o menos espagueti y no hay una manera fácil de asegurarse de que todas estas sobrecargas sean utilizadas por todo. Hay incluye bibliotecas de terceros que son black-box. También usamos STL en todas partes.

En mis pruebas, he encontrado que STL todavía está mezclando llamadas a mi propia nueva/eliminar y las llamadas nuevas/eliminar MSVC estándar.

No parece realista incluir mi archivo de encabezado en miles de otros archivos, eso solo llevaría demasiado tiempo. ¿Alguien puede ofrecer algunos consejos sobre cómo sobrecargar correcta y eficazmente nuevo/eliminar globalmente para que todo use mi administrador de memoria personalizado?

+0

Si define los operadores a nivel mundial en un encabezado precompilado que debe cubrir más terreno. De forma alternativa, puede usar las funciones de pilas CRT si esto es para detectar fugas de memoria. – AJG85

Respuesta

63

Así no es como funciona esto. Usted reemplazar los dos operadores, y esto se hace en enlace tiempo. Todo lo que necesita hacer es escribir una sola TU que defina estos operadores y vincularla a la mezcla. Nadie más necesita saber acerca de esto:

// optional_ops.cpp 

void * operator new(std::size_t n) throw(std::bad_alloc) 
{ 
    //... 
} 
void operator delete(void * p) throw() 
{ 
    //... 
} 

En principio, no hay necesidad de que todos los archivos de cabecera para declarar estas funciones (operator new, operator delete), ya que los declaraciones de esas dos funciones ya están codificados en el idioma, si quieres. Sin embargo, los nombres std, std::bad_alloc y std::size_t son no predefinidos, por lo que es probable que desee incluir <new> o algún otro encabezado para proporcionar esos nombres.

En C++ 11 y versiones posteriores, puede utilizar decltype(sizeof(0)) para obtener el tamaño del primer parámetro de forma que no requiera ningún tipo de biblioteca. C++ 11 también tiene un modelo de excepción más simple sin especificaciones de excepción dinámica (que finalmente fueron eliminadas del lenguaje por completo en C++ 17).

void * operator new(decltype(sizeof(0)) n) noexcept(false) 
{ 
    //... 
} 
+1

¿No se queja el enlazador de las definiciones duplicadas? Creo que la ODR se aplica aquí. Sin mencionar que tenemos 120 DLL que construimos, y tendría que vincularlo en cada uno de esos proyectos DLL. Supongo que esto es mejor que las alternativas. –

+3

@RobertDailey: No, caso especial, cubierto por el estándar, referencias débiles, etc. De hecho, informé de un error en GCC el otro día, así que con la última versión esto debería incluso funcionar con '-fwhole-programme' y '-flto' y whatnot (ver [aquí] (http://stackoverflow.com/questions/7629270/how-does-stdstring-allocate-memory-in-gcc-with-fwhole-program) y [aquí] (http : //gcc.gnu.org/bugzilla/show_bug.cgi? id = 50594).) ' –

+0

¿Podría explicar a qué se refiere con" cubierto por el estándar "y" referencias débiles "? ¡¡Gracias!! –

31

añadir también estas líneas:

void *operator new[](std::size_t s) throw(std::bad_alloc) 
{ 
    // TODO: implement 
    return NULL; 
} 
void operator delete[](void *p) throw() 
{ 
    // TODO: implement 
} 
Cuestiones relacionadas