2010-08-13 31 views
8

Estoy trabajando en una aplicación Win32 C++ en Visual Studio.Destructor crash

En uno de los archivos fuente, tengo un objeto global como el siguiente.

TestClass tObj; 

int main() //Execution starts here 
{ 
} 

TestClass se define en otra DLL como la de continuación.

struct Source 
{ 

}; 

class TestClass 
{ 
    list<Source> sourceList; 
    public: 
     TestClass() {} 
     ~TestClass() {} 
}; 

Mientras que mi aplicación se está ejecutando, si trato de cerrar la aplicación explícita, cerrando la ventana de la consola, que está fallando en TestClass destructor. Callstack muestra que CrtIsValidHeapPointer está fallando.

Pls me ayudan a resolver este problema.

+0

Utilice cuatro espacios para sangrar el código y ninguno para el texto normal. –

+1

¿Has construido el exe y la DLL con el mismo tiempo de ejecución de C++? – Mark

+0

Sí, construí ambos con Visual Studio. Solo el tipo de configuración es diferente. Uno es exe y otro es la configuración de DLL en la configuración del proyecto. – bjskishore123

Respuesta

4

Asegúrese de compilar el EXE y la DLL con el mismo tiempo de ejecución, preferiblemente con el tiempo de ejecución dinámico.

+0

El bloqueo se resuelve utilizando la biblioteca Same runtime en exe y dll. Gracias a todos por ayudarme – bjskishore123

1

Se está cayendo en el destructor, se está produciendo una excepción desde el destructor que llama a terminar y bloquear su aplicación. Uncaught exceptions

Hay dos situaciones en las que se llama a un destructor. El primero es cuando un objeto se destruye bajo condiciones "normales", por ejemplo, cuando sale del alcance o se elimina explícitamente. El segundo es cuando un objeto es destruido por el mecanismo de manejo de excepciones durante la parte de desenrollado de la propagación de la excepción. Debe escribir sus destructores bajo el supuesto conservador de que una excepción es activo, ya que si el control deja un destructor debido a una excepción, mientras que otra excepción es activa, C++ llama a la función terminan

+0

El objeto global se está construyendo antes de llamar a main(). Así que creo, su destrucción está sucediendo después de las salidas principales(). En ese momento, la lista sourceList head que STL utiliza internamente, no es válida en el momento de la liberación. Por lo tanto, CrtIsValidHeapPointer está fallando. – bjskishore123

+0

La pregunta es: ¿por qué la cabecera sourceList no es válida? Si su exe y DLL están construidos correctamente con tiempos de ejecución compatibles, entonces este código debería funcionar bien. El tiempo de ejecución limpiará los objetos globales antes de liberar el montón. –

+0

El bloqueo se resuelve utilizando la biblioteca Same runtime en exe y dll. Gracias a todos por ayudarme. – bjskishore123

1

objetos globales se inicializan y destruidos por la C tiempo de ejecución. Se inicializan antes de que se llame main y se destruya después de que regrese.

El error probablemente sea causado por algo a lo que se accede desde su destructor TestClass (o indirectamente desde un destructor Source). El código de destructor está accediendo a la memoria no válida (o memoria que ya se ha liberado).

El orden de inicialización y destrucción de las variables globales no está definido, y con frecuencia es una fuente de errores en la finalización de la aplicación. Si hay otros elementos globales que podrían limpiar o modificar recursos a los que hace referencia TestClass, este podría ser el culpable.

+0

No agrego ningún nodo a la lista de origen (enumere ). La lista está vacía en el momento de la llamada al destructor. Pero aún así, STL List tendrá un puntero principal oculto internamente. Mientras trata de liberar eso, se cuelga. – bjskishore123

+0

¿Con qué CRT (s) está compilando el EXE y el DLL? –

0

¿Están el DLL y el EXE construidos usando la misma alineación (paquete pragma)?

9

Su problema es que las diferentes configuraciones de compilador/enlazador entre el .exe y .dll están causando efectivamente los archivos .dll y .exe sea utilizando diferentes implementaciones de la biblioteca estándar:

  • debe utilizar la misma indicadores de preprocesador * para compilar tanto .exe como .dll; de lo contrario, cada binario compilará con implementaciones sutilmente diferentes.
  • Debe vincular tanto el .exe como el .dll al tiempo de ejecución dinámico. Los binarios vinculados de forma estática con el tiempo de ejecución obtienen su propio montón, y terminas asignando en un montón e intentando liberar en otro.

Para solucionar este problema, vaya a Project > Properties > Configuration Properties > C/C++ > Code Generation y cambie la opción de biblioteca de tiempo de ejecución para Multi-threaded Debug DLL (/MDd). Debe hacer esto tanto para el proyecto .exe como para el proyecto .dll.

A partir de Visual Studio 2010, algunos de estos tipos de errores se detectarán en el momento del enlace utilizando #pragma detect_mismatch.

* Para todas las banderas del preprocesador que tienen algún efecto de la implementación de la biblioteca estándar

+0

'+ 1' de mi parte para esta respuesta completa. @ bjskishore123: Lea el [FAQ] (http://stackoverflow.com/faq). Se le anima a aceptar la respuesta que cree que le ayudó más a resolver su problema. – sbi

0

tratar de hacer su constructor y el destructor no en línea, que pueden ayudar. Si ctor y dtor no están en línea, ambos se generarán en nombre de dll, por lo que la construcción y destrucción de la lista <> se ejecutará con la misma biblioteca de tiempo de ejecución. Generalmente, trate de evitar pasar objetos stl opacos a través de los límites dll. Es mejor encapsularlos como miembros de privatte en sus propias clases y proporcionar métodos no alineados para manipular dichos miembros.