c gcc malloc assertion

¿Por qué obtengo una falla de aserción C malloc?



gcc assertion (7)

Estoy implementando un algoritmo polinomial de división y conquista para poder compararlo con una implementación de OpenCL, pero no puedo hacer que malloc funcione. Cuando ejecuto el programa, asigna un montón de cosas, comprueba algunas cosas y luego envía el size/2 al algoritmo. Luego, cuando vuelvo a golpear la línea de malloc , escupe esto:

malloc.c: 3096: sYSMALLOc: Assertion `(old_top == ((mbinptr) (((char *) & ((av) -> bins [((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size)> = (unsigned long) ((((__ builtin_offsetof (struct malloc_chunk, fd_nextsize)) + ((2 * (sizeof (size_t))) - 1)) & ~ ((2 * (sizeof) (size_t))) - 1))) && ((old_top) -> size & 0x1) && ((unsigned long) old_end & pagemask) == 0) ''failed. Abortado

La línea en cuestión es:

int *mult(int size, int *a, int *b) { int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2; fprintf(stdout, "size: %d/n", size); out = (int *)malloc(sizeof(int) * size * 2); }

Comprobé el tamaño con un fprintf , y es un entero positivo (generalmente 50 en ese punto). Traté de llamar malloc con un número simple también y sigo teniendo el error. Estoy perplejo por lo que está pasando, y nada de Google que he encontrado hasta ahora es útil.

¿Alguna idea de qué está pasando? Estoy intentando descubrir cómo compilar un GCC más nuevo en caso de que sea un error del compilador, pero realmente lo dudo.


99.9% probable de que haya dañado la memoria (sobre o bajo flujo de un búfer, escribió en un puntero después de que se liberó, se liberó dos veces en el mismo puntero, etc.)

Ejecute su código en Valgrind para ver dónde su programa hizo algo incorrecto.


Estaba portando una aplicación de Visual C a gcc sobre Linux y tuve el mismo problema con

malloc.c: 3096: sYSMALLOc: Afirmación usando gcc en UBUNTU 11.

Moví el mismo código a una distribución de Suse (en otra computadora) y no tengo ningún problema.

Sospecho que los problemas no están en nuestros programas sino en la propia libc.


Obtuvimos este error porque olvidamos multiplicar por sizeof (int). Tenga en cuenta que el argumento para malloc (..) es un número de bytes, no el número de palabras de la máquina o lo que sea.


Para darte una mejor comprensión de por qué sucede esto, me gustaría ampliar un poco la respuesta de @ r-samuel-klatchko.

Cuando llamas a malloc , lo que realmente está sucediendo es un poco más complicado que solo darte un pedazo de memoria para jugar. Debajo del capó, malloc también guarda cierta información de limpieza sobre la memoria que le ha dado (más importante, su tamaño), de modo que cuando llame free , sepa cosas como la cantidad de memoria para liberar. Esta información normalmente se guarda justo antes de que malloc le devuelva la ubicación de la memoria. Se puede encontrar información más exhaustiva en Internet ™ , pero la idea (muy) básica es algo como esto:

+------+-------------------------------------------------+ + size | malloc''d memory + +------+-------------------------------------------------+ ^-- location in pointer returned by malloc

Sobre la base de esto (y simplificando las cosas en gran medida), cuando llamas a malloc , necesita obtener un puntero a la siguiente parte de la memoria que está disponible. Una forma muy simple de hacerlo es mirar el bit de memoria anterior que regaló y mover los bytes de size más abajo (o arriba) en la memoria. Con esta implementación, terminas con tu memoria buscando algo así después de asignar p1 , p2 y p3 :

+------+----------------+------+--------------------+------+----------+ + size | | size | | size | + +------+----------------+------+--------------------+------+----------+ ^- p1 ^- p2 ^- p3

Entonces, ¿qué está causando tu error?

Bueno, imagine que su código escribe erróneamente más allá de la cantidad de memoria que ha asignado (ya sea porque asignó menos de lo que necesitaba ya que era su problema o porque está usando las condiciones de frontera incorrectas en algún lugar de su código). Supongamos que su código escribe tantos datos en p2 que comienza a sobrescribir lo que está en el campo de size p3 . Cuando ahora llame a malloc , verá la última ubicación de memoria que devolvió, observe su campo de tamaño, vaya a p3 + size y luego comience a asignar memoria desde allí. Sin embargo, dado que su código ha sobrescrito el size , esta ubicación de memoria ya no está después de la memoria previamente asignada.

¡No hace falta decir que esto puede causar estragos! Los implementadores de malloc , por lo tanto, han incluido una serie de "aseveraciones", o comprobaciones, que intentan hacer un montón de chequeos de cordura para detectar esto (y otros problemas) si están por suceder. En su caso particular, estas afirmaciones son violadas y, por lo tanto, malloc aborta, diciéndole que su código estaba a punto de hacer algo que realmente no debería estar haciendo.

Como se dijo anteriormente, esto es una simplificación excesiva, pero es suficiente para ilustrar el punto. La implementación glibc de malloc tiene más de 5k líneas, y ha habido una gran cantidad de investigaciones sobre cómo construir buenos mecanismos de asignación de memoria dinámica, por lo que no es posible cubrir todo en una respuesta SO. Sin embargo, afortunadamente, esto te ha dado una idea de lo que realmente está causando el problema.


Probablemente estás sobrepasándote más allá de la memoria asignada en alguna parte. entonces el sw subyacente no lo detecta hasta que se llame malloc

Puede haber un valor de protección destruido que está siendo atrapado por malloc.

editar ... agregado esto para límites verificando ayuda

http://www.lrde.epita.fr/~akim/ccmp/doc/bounds-checking.html


Recibí el siguiente mensaje, similar al tuyo:

program: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)'' failed.

Cometí un error al invocar algún método antes, al usar malloc. Erróneamente sobrescribió el signo de multiplicación ''*'' con un ''+'', al actualizar el factor después de sizeof () - operador al agregar un campo a una matriz de caracteres sin signo.

Aquí está el código responsable del error en mi caso:

UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5); b[INTBITS]=(some calculation); b[BUFSPC]=(some calculation); b[BUFOVR]=(some calculation); b[BUFMEM]=(some calculation); b[MATCHBITS]=(some calculation);

En otro método posterior, utilicé malloc nuevamente y produjo el mensaje de error que se muestra arriba. La llamada fue (lo suficientemente simple):

UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

Pensar usando el signo ''+'' en la primera llamada, lo que conduce a cálculos erróneos en combinación con la inicialización inmediata de la matriz después (sobrescribir la memoria que no estaba asignada a la matriz), generó cierta confusión en el mapa de memoria de malloc. Por lo tanto, la segunda llamada salió mal.


Tengo el mismo problema, utilicé malloc sobre n una vez más en un bucle para agregar nuevos datos de cadena de caracteres *. Me enfrenté al mismo problema, pero después de liberar la memoria asignada, el problema void free() se resolvió