Error de memoria y relacionados

¡Puaj! Creo que tengo uno de esos oscuros errores de memoria. Pero no estoy seguro. Es posible que ni siquiera esté en mi parte del código. Estoy probando una aplicación (C++) en MS VC++ 2005. En este momento, mi código arroja una excepción y se rompe debido a un error de almacenamiento dinámico en un retroceso de vector aparentemente inofensivo:

std::vector<int> blah;
for(int i=0; i<somesize; ++i) {
   blah.push_back(0);
}

No importa dónde mueva este segmento del código, la falla ocurre exactamente en el retroceso. ¡Esto es Loco! Estoy seguro de que no hay nada ilegal en este uso. Además, cuando lo comento, pasa sin ningún problema. Arriba y abajo tengo otros vectores que puedo cargar sin problemas. Relacionado con eso, tengo otra pregunta sobre cómo hacer esto:

std::vector<double*> wha;
wha.push_back(nil);
..
... 
wha[0] = some pointer I create;

La pregunta que tengo es: cuando lo que sale del alcance, no debería eliminar el puntero, ¿verdad? Creo que tengo razón en eso, pero mejor aclarar. Lo siento, no hay muchos detalles, pero avíseme si algún detalle adicional ayuda e intentaré publicar más. Gracias.

Edit:

El mensaje de error exacto es:

First-chance exception at 0x771b70cd in myprogram_run.exe: Microsoft C++ exception: 
H5::FileIException at memory location 0x08026ca0..
First-chance exception at 0x771b70cd in myprogram_run.exe: Microsoft C++ exception: 
H5::FileIException at memory location 0x08026ca0..
'myprogram_run.exe': Loaded 'C:\Windows\System32\wdmaud.drv', No symbols loaded.
...
...
''myprogram_run.exe': Unloaded '<path\to>\bin\win64-x64-vs2005.shared\tcl85.dll'
The thread 'Win64 Thread' (0x23a8) has exited with code 0 (0x0).
The thread 'Win64 Thread' (0x120c) has exited with code -1 (0xffffffff).
The thread 'Win64 Thread' (0x27bc) has exited with code -1 (0xffffffff).
...
...
HEAP[myprogram_run.exe]: HEAP: Free Heap block dfd6870 modified at dfd68d0 after it was freed
Windows has triggered a breakpoint in myprogram_run.exe.

This may be due to a corruption of the heap, and indicates a bug in myprogram_run.exe or any of 
the DLLs it has loaded.

The output window may have more diagnostic information 
The program '[3052] myprogram_run.exe: Native' has exited with code -1 (0xffffffff).

¿Debería preocuparme por las H5::FileIExceptions? Lo vinculamos como una DLL de terceros.

preguntado el 12 de junio de 12 a las 17:06

Un tema de pregunta por publicación, por favor... -

Los punteros desnudos en los contenedores deben eliminarse explícitamente, de ahí la necesidad de punteros inteligentes. ¿Y qué muestra la depuración? Y por qué retroceder (0), no push_back(i) ? -

Necesitas conseguir un ejemplo mínimo que reproduce tu problema. El código publicado no tiene el problema, por lo que nadie puede ayudarlo sin adivinar. Lo más probable es que al tratar de limitarse a un ejemplo de este tipo, encuentre el problema usted mismo. -

¿Puedes minimizar el código? Es decir, eliminar todo. más que puedas, sin cambiar el (mal) comportamiento. Eventualmente, encontrará el error u obtendrá algo lo suficientemente pequeño como para publicarlo. Para la segunda pregunta, no, no debe intentar eliminar el objeto señalado. -

Un compañero de trabajo mío tuvo un problema muy similar al iterar un vector... resultó que la llamada de función anterior era a una biblioteca externa, y el encabezado en el que se declaró la llamada había especificado la convención de llamada incorrecta, lo que estaba causando estragos en el apilar. Entonces podría ser algo completamente ajeno al vector. -

2 Respuestas

  1. El código que publicaste está bien. Una corrupción de la memoria puede haber ocurrido en otro lugar, y el push_back solo lo está revelando.
  2. nil no se eliminará. Cada vez que usas push_back, se inserta una copia del puntero en el vector. Lo único que se elimina es la matriz interna que contiene todas las copias de los punteros.

Respondido el 12 de junio de 12 a las 18:06

En general, lo primero que debe hacer al experimentar daños en el montón es habilitar alguna forma de "depuración malloc", la mayoría de las plataformas tienen esto.

En VC++2005, aparentemente solo puedes #define _DEBUG. Esto convierte malloc() en _malloc_dbg(), que incluye información de depuración (como archivo/línea) y relleno para comprobar si hay desbordamientos/insuficiencias de búfer. Ver también El montón de depuración de CRT.

EDIT: Si eso no ayuda (y a menudo no lo hace), puede usar un malloc de depuración que coloca una "página de protección" después de cada asignación, por ejemplo DUMA o OSX libgmalloc. Esto no está habilitado de forma predeterminada en las compilaciones de depuración porque la sobrecarga es enorme (hasta ~ 8K por asignación), pero hace que la depuración sea un problema. mucho más más rápido (y detecta el mal acceso en lugar de una llamada posterior a malloc()/free()/la función de verificación de montón).

(Recientemente arreglé un ~ bloqueo semanal que he estado soportando durante años ¡posiblemente más de una década! No estoy seguro de cómo no se me ocurrió hacer esto antes, dado que conozco libgmalloc desde hace casi el mismo tiempo y lo usé para depurar la corrupción del montón en el trabajo).

Respondido el 13 de junio de 12 a las 20:06

Sin embargo, ¿podrías ser un poco más específico? ¿Dónde debo definir #define _DEBUG? Además, ¿no sería eso el equivalente a ejecutar en modo de depuración? (es decir, dicha directiva de precompilador debe establecerse automáticamente cuando se ejecuta en depuración, ¿no?) - aplastado bugaboo

Acabo de probar esto... realmente no me dio más información de la que ya estaba viendo. - aplastado bugaboo

En realidad, descubrí cómo y lo hice bien (Proyecto->Propiedades->C/C++->Definiciones de preprocesador); así como también tuve que agregar las definiciones de inclusión y preprocesador en main() #define _CRTDBG_MAP_ALLOC #include #incluir y la llamada a _CrtDumpMemoryLeaks(); pero no obtengo la salida detallada con los números de línea, etc. ¿Alguna idea? - aplastado bugaboo

Esperaría que apareciera cerca del Free Heap block ... modified at ... after it was freed mensaje, aunque es posible que la información del archivo/línea se borre cuando se libera el bloque. Respuesta editada para incluir DUMA. - tc.

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.