2012-10-10 10 views
6

La biblioteca de tiempo de ejecución de Microsoft proporciona la versión de depuración de las funciones de asignación. Para C++ esta es una variante de depuración del operador de nuevo con la firma:Anulación de nuevo con la versión de depuración sin dañar la ubicación nueva

void *operator new(size_t size, int blockType, const char *filename, int linenumber); 

y una macro se define como

#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) 

Ahora a instrumento todas las asignaciones, uno normalmente define

#if defined DEBUG_NEW 
#define new DEBUG_NEW 
#endif 

Sin embargo, esta definición interrumpe cualquier lugar que utilice la ubicación nueva, porque los dos conjuntos de argumentos terminan siendo un error de sintaxis. Ahora puedo manejar fácilmente los pocos usos en nuestro código, pero la biblioteca estándar y la ubicación de uso de impulso nueva por todo el lugar. Definir esto globalmente significa incluir muchas cosas antes de la definición y eso ralentiza la compilación.

Entonces, ¿habría alguna forma de asignar instrumentos en nuestro código sin tener que colocar los encabezados simplemente porque contienen la ubicación nueva y sin tener que poner la última definición en todos los archivos o escribir DEBUG_NEW manualmente?

Respuesta

0

Todo esto DEBUG_NEW debe morir en el fuego! Solo fue apenas útil y no es útil en el C++ moderno en absoluto, porque ya no se ve new en C++.

Hubo mejores opciones como DUMA y ahora que hay Dr. Memory (que funciona de manera similar a Valgrind, pero en Windows), no tiene absolutamente ningún sentido utilizar la abominación DEBUG_NEW.

3

La forma en que he resuelto este históricamente es mediante el uso de encabezados precompilados, y hacer algo como esto (StdAfx.h, Pch.h, PreCompiled.h o lo que sea):

//First include all headers using placement new 
#include <boost/tuple/tuple.hpp> 
#include <vector> 

#define new MY_NEW 
#define MY_NEW new(__FILE__, __LINE__) 

Y a continuación, asegúrese ningún archivo incluye los encabezados de impulso directamente, sino solo el encabezado precompilado.

+0

Encabezados precompilados sería realmente doloroso mantener en nuestra situación. Serían realmente grandes y complejos debido a diversos problemas de portabilidad (la base de código está compilada para 4 plataformas muy diferentes). –

+0

¿De qué manera serían difíciles de mantener? El pch debe cambiar muy poco. –

+0

Si incluye las cosas de impulso, cambiaría con bastante frecuencia. Pero quizás debería intentar precompilar solo este encabezado de depuración de memoria (que se inyecta con la opción del compilador '/ Fi'); la colocación nueva aparece en considerablemente menos lugares. –

-1

define new DEBUG_NEW línea se debe colocar en un archivo de origen, después de todas las líneas #include. De esta forma, se aplica solo a su propio código y no se aplica a ningún otro archivo h como Boost. La nueva rediseño global DEBUG_NEW puede hacer que la compilación falle y debe evitarse.

+0

Tiene razón, excepto que, como ve, la pregunta fue explícitamente ** SIN HACER ESO **. –

+0

Buen ejemplo de votación sin leer la respuesta. –

5
#pragma push_macro("new") 
#undef new 

new(pointer) my_class_t(arg1, arg2); 

#pragma pop_macro("new") 

o

#pragma push_macro("new") 
#undef new 

#include <...> 
#include <...> 
#include <...> 

#pragma pop_macro("new") 
+0

Sería útil describir cómo funcionan 'push_macro()' y 'pop_macro()'. Tal como, ¿el 'nuevo 'original se restaura después de' pop_macro ("nuevo") '. – cpburnz

0

Sé que esto es un poco tarde, pero ese problema se puede resolver mediante el uso de la magia plantilla.

Últimamente he estado codificando un depurador debug_new, que agrega una nueva palabra clave "ubicación", que se escribe delante de todas las nuevas llamadas de ubicación.

Se puede extraer de mi depurador aquí: https://sourceforge.net/projects/debugnew/

O el depurador DEBUG_NEW de Nvwa aquí: https://sourceforge.net/projects/nvwa/

+0

¿Podría incluir una explicación de cómo y por qué funciona? –

Cuestiones relacionadas