2011-04-19 11 views
6

Estoy depurando un defecto y lo he reducido al puntero vtable para un objeto que es 0xdddddddd. This answer indica que las versiones de depuración de Win32 generalmente establecerán la memoria inactiva, o la memoria que se ha eliminado, a este valor especial.¿Qué puede hacer que el puntero de VTable sea 0xdddddddd en la compilación de depuración de Win32?

Tenga en cuenta que el puntero sí parece válida, es sólo la puntero vtable que es 0xdddddddd.

He aquí un fragmento de código:

std::list<IMyObject*>::const_iterator it; 
for (it = myObjects.begin(); it != myObjects.end(); ++it) 
{ 
    IMyObject* pMyObject = *it; 
    if (pMyObject == 0) 
     continue; 

    pMyObject->someMethod(); // Access violation  
} 

Si rompo en la línea de la violación de acceso y ver pMyObject, puedo ver que pMyObject en sí tiene una dirección válida (0x08ede388), pero el miembro __vfptr no es válido (0xdddddddd).

Algunas notas:

  • Es una aplicación de un solo subproceso, así que esto es muy probable que no una condición de carrera o un problema de exclusión mutua.
  • No parece haber ningún problema obvio como eliminar el objeto más arriba en la pila de llamadas antes de acceder a él.
  • Este problema sólo parece ser reproducibles en el servidor Windows 2008, pero no en Windows 7.

Cualquier sugerencia sobre cómo depurar esta otra?

+0

Esto parece un caso clásico de alguien que elimina el objeto después de colocar el puntero en la lista. ¿Está seguro de que ese no es el caso (podría eliminarse de alguna otra función después de completar la lista, por lo que echar un vistazo a la pila de llamadas puede no ser de mucha ayuda). Lo más simple es intentar poner un punto de interrupción en el destructor de 'IMyObject' y ver que alguien está eliminando el objeto. – Naveen

Respuesta

7

Está utilizando el puntero después de que se haya liberado. Obtenga un seguimiento de la pila de un punto de interrupción en el destructor para ver qué está borrando. O mejor aún, use shared_ptr <> para evitar el problema.

+0

Gracias, estos objetos se crean/destruyen miles de veces, por lo que esto podría ser difícil (ni siquiera estoy seguro de que un punto de interrupción condicional ayude porque no estoy seguro de cuál sería la condición). Pero comenzaré a investigar. – LeopardSkinPillBoxHat

+1

Está buscando un caso en el que se elimine el objeto sin que se elimine el puntero de la lista, o un caso en el que un objeto podría insertarse en la lista más de una vez, pero solo se eliminará de la lista una vez en la eliminación. – janm

+0

@LeopardSkinPillBoxHat: ... o un caso en el que el objeto se agrega a la lista y luego se elimina fuera de la lista. El enfoque simple es evitar punteros crudos y almacenar uno de los punteros inteligentes disponibles ('QSharedPointer' podría ser un buen candidato). –

0

Si inicia el programa, ponga un punto de interrupción en donde cree el objeto. A continuación, agregue un punto de interrupción de la memoria. Se disparará si sobrescribe o elimina la memoria. Bueno, o cámbialo de cualquier forma.

Su objeto se verá correctamente si la memoria no se sobrescribe, pero su vtable puede no estar dependiendo de los detalles del compilador.

También podría ser un problema de tamaño si está utilizando la herencia. Si está utilizando cualquier tipo de memoria de depósito o almacenando objetos por cualquier cosa que no sea el puntero.

0

Si pMyObject-> someMethod() finalmente termina modificando la lista myObjects invalidará cualquiera de los iteradores actuales.

Además, si los datos del puntero ya están eliminados, esto provocará el mismo problema.

Cuestiones relacionadas