2010-03-20 16 views
26

Tengo un error bastante serio en mi programa: llamadas ocasionales a new() arrojan bad_alloc.Estrategia de depuración para encontrar la causa de bad_alloc

De la documentación que puedo encontrar en bad_alloc, parece ser arrojado por estas razones:

  1. Cuando el ordenador se queda sin memoria (que definitivamente no está pasando, tengo 4 GB de RAM, programa arroja bad_alloc cuando usa menos de 5MB (comprobado en taskmanager) sin ejecutar nada serio en el fondo).

  2. Si la memoria se fragmenta demasiado para asignar nuevos bloques (lo cual, una vez más, es improbable, el bloque de mayor tamaño que he asignado sería de 1 KB y no se hace más de 100 veces antes de que ocurra el bloqueo))

Basado 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 hilo, lo que posiblemente podría estar contribuyendo al problema. Al probar todos los objetos en un solo hilo, todo parece funcionar sin problemas. La única otra cosa que puedo pensar que está sucediendo aquí podría ser algún tipo de condición de carrera provocada al llamar a new() en más de un lugar al mismo tiempo, pero he intentado agregar mutexes para evitar ese comportamiento. sin efecto.

Como el programa tiene varios cientos de líneas y no tengo idea de dónde se encuentra realmente el problema, no estoy seguro de qué fragmentos de código, si es que hay alguno, se publicarán. En cambio, 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 enhebrar.

Respuesta

16

Otro posible problema es que, si bien se menciona que el programa está utilizando menos de 5 MB, usted no menciona la cantidad de espacio que está tratando de asignar. Podría tener alguna condición de carrera que corrompa el valor que usa para determinar el tamaño de asignación, y podría estar tratando de asignar 37TB o algunas tonterías.

No es particularmente probable, supongo, pero vale la pena consultarlo.

+0

En realidad ese era el problema ... ni idea de dónde estaba exactamente el problema, pero hay muchas variables destrozadas deambulando en lugares extraños, parece que había una condición de carrera en alguna parte. ¡Gracias! – Salami

+0

Ese fue mi caso ... pensé que estaba llamando 'new char [_len]', pero estaba llamando 'new char [len]' cuando 'len' no se había inicializado, por lo que probablemente era un número enorme. Realmente ayudó a pensar cuánto espacio estoy pidiendo y a mirar los valores más cerca. Gracias por la respuesta. – flcoder

3

algunas aclaraciones:

Cada proceso en ventanas recupera la memoria virtual de 4 GB, 2 GB, de los cuales es para el espacio de usuario y el restante para el espacio del núcleo. Los 4 GB de RAM no contribuirán a la memoria virtual, pero sí a la memoria física.

En la memoria de 2GB, todo EXE, DLL se carga y apenas 1.6 - 1.7GB disponible para la asignación de memoria. En esta memoria, si no hay memoria contigua para la asignación, la asignación de memoria falla.

+0

¿sabes acerca de los sistemas linux/unix cuánto asignan? – anish

20

bad_alloc también se puede lanzar cuando tiene un error que sobrescribe los punteros que el montón utiliza para administrar el grupo de memoria que utiliza para asignar.

La causa más común de esto es que está escribiendo más allá del final de un bloque asignado de memoria, (o antes del inicio, pero eso es menos común). Casi tan común es escribir en un bloque de memoria después de haber sido liberado. Esto se llama corrupción de montón.

Además, debería tener en cuenta que un proceso de 32 bits en Windows tiene un máximo de 2 GB de espacio de direcciones (3 GB para programas con gran capacidad de direcciones). Esto es independientemente de la cantidad de RAM que haya instalado, la memoria es virtual y las asignaciones no fallan hasta que se agote el espacio de direcciones, incluso si solo tiene 1 GB de RAM.

Aquí es una buena discusión de corrupción de memoria en C++ http://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm

+0

Gracias por la información aquí también. – Salami

1

bad_alloc puede ser lanzado por otro código también.

Lo he visto utilizado por un conjunto limitado de memoria diseñado para uso con contenedores STL. Cuando se alcanzó el límite de tamaño, lanzó bad_alloc y el software solo tuvo que manejarlo.

0

En realidad tuve este problema antes y lo 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 compilarse).

Cuestiones relacionadas