c++ - Estrategia de depuración para encontrar la causa de bad_alloc.
debugging bad-alloc (5)
Algunas aclaraciones:
Cada proceso en Windows obtiene 4 GB de memoria virtual, de los cuales 2 GB son para espacio de usuario y restante para espacio de kernel. Los 4 GB de RAM no contribuyen a la memoria virtual, pero son para la memoria física.
En la memoria de 2GB, todos los archivos EXE, DLL se cargan y apenas 1.6 - 1.7GB disponibles para la asignación de memoria. En esta memoria, si no hay memoria contigua para la asignación, la asignación de memoria falla.
Tengo un error bastante serio en mi programa: llamadas ocasionales a new () lanzan un bad_alloc.
De la documentación que puedo encontrar en bad_alloc, parece que se lanza por estas razones:
Cuando la computadora se queda sin memoria (lo que definitivamente no está sucediendo, tengo 4GB de RAM, el programa lanza bad_alloc cuando uso menos de 5MB (registrado en el administrador de tareas) sin nada serio ejecutándose en segundo plano).
Si la memoria se fragmenta demasiado para asignar nuevos bloques (lo cual, nuevamente, es improbable, el bloque de mayor tamaño que asigno sería aproximadamente 1 KB, y eso no se hace más de 100 veces antes de que se produzca el bloqueo).
Basándome en estas descripciones, realmente no tengo ningún lugar en el que se pueda lanzar un bad_alloc.
Sin embargo, la aplicación que estoy ejecutando ejecuta más de un subproceso, lo que podría contribuir al problema. Al probar todos los objetos en un solo hilo, todo parece funcionar sin problemas. La única otra cosa en la que puedo pensar que está sucediendo aquí podría ser algún tipo de condición de carrera causada por llamar a new () en más de un lugar al mismo tiempo, pero he intentado agregar mutex para evitar ese comportamiento. sin efecto.
Debido a que el programa tiene varios cientos de líneas y no tengo idea de dónde radica realmente el problema, no estoy seguro de qué fragmentos de código, si es que hay alguno, publicar. En su lugar, me preguntaba si había alguna herramienta que me ayudara a probar este tipo de cosas, o si hay alguna estrategia general que pueda ayudarme con este problema.
Estoy usando Microsoft Visual Studio 2008, con Poco para subprocesos.
De hecho, tuve este problema antes y se solucionó al limpiar y reconstruir el proyecto. Siempre vale la pena intentarlo cuando tienes un comportamiento extraño (a menos que sea un proyecto enorme que demore horas en compilarlo).
Otro posible problema es que, si bien mencionas que el programa está usando menos de 5 MB, no mencionas cuánto espacio está tratando de asignar. Podría tener alguna condición de carrera que esté corrompiendo el valor que usa para determinar el tamaño de la asignación, y podría estar tratando de asignar 37 TB o algo así como tonterías.
No es particularmente probable, supongo, pero vale la pena comprobarlo.
bad_alloc puede ser lanzado por otro código también.
Lo he visto usado por un grupo de memoria limitante diseñado para usarse con contenedores STL. Cuando se alcanzó el límite de tamaño, lanzó bad_alloc y el software solo tuvo que manejarlo.
bad_alloc también se puede lanzar cuando tienes un error que está sobrescribiendo los punteros que el montón utiliza para administrar el conjunto de memoria que utiliza para asignar.
La causa más común de esto es que estás escribiendo más allá del final de un bloque de memoria asignado (o antes del inicio, pero eso es menos común). Casi tan común es escribir en un bloque de memoria después de que se haya liberado. Esto se llama corrupción del montón.
Además, debo señalar que un proceso de 32 bits en Windows tiene como máximo 2 GB de espacio de direcciones (3 GB para programas con gran capacidad de dirección). Esto es independiente de la cantidad de RAM que haya instalado, la memoria es virtual y las asignaciones no fallan hasta que se queda sin espacio de direcciones, incluso si solo tiene 1 GB de RAM.
Aquí hay una buena discusión sobre la corrupción de la memoria en C ++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm