Error: gratis (): siguiente tamaño no válido (rápido):

90

¿Qué es este extraño error que recibo? Estoy compilando C ++ usando g ++ en Ubuntu 10.10. Aparece aleatoriamente cuando ejecuto el ejecutable (tal vez 2 veces en 8 horas, con 10 compilaciones por hora). Sin embargo, si limpio y recompilo, desaparece la mayor parte del tiempo.

*** glibc detected *** ./emailQueue.app: free(): invalid next size (fast): 0x0000000001c40270 ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7f490d95e4b6]
/lib/libc.so.6(cfree+0x73)[0x7f490d964c83]
./emailQueue.app[0x401f47]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7f490d905d8e]
./emailQueue.app[0x401cc9]
======= Memory map: ========
00400000-0040d000 r-xp 00000000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
0060d000-0060e000 r--p 0000d000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
0060e000-0060f000 rw-p 0000e000 08:01 1311132                            /home/server/Projects/email/emailQueue.app
01c40000-01c82000 rw-p 00000000 00:00 0                                  [heap]
7f4908000000-7f4908021000 rw-p 00000000 00:00 0 
7f4908021000-7f490c000000 ---p 00000000 00:00 0 
7f490ce52000-7f490ce5e000 r-xp 00000000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490ce5e000-7f490d05d000 ---p 0000c000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05d000-7f490d05e000 r--p 0000b000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05e000-7f490d05f000 rw-p 0000c000 08:01 1051251                    /lib/libnss_files-2.12.1.so
7f490d05f000-7f490d075000 r-xp 00000000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d075000-7f490d275000 ---p 00016000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d275000-7f490d276000 r--p 00016000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d276000-7f490d277000 rw-p 00017000 08:01 1048770                    /lib/libz.so.1.2.3.4
7f490d277000-7f490d28e000 r-xp 00000000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d28e000-7f490d48d000 ---p 00017000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48d000-7f490d48e000 r--p 00016000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48e000-7f490d48f000 rw-p 00017000 08:01 1051248                    /lib/libnsl-2.12.1.so
7f490d48f000-7f490d491000 rw-p 00000000 00:00 0 
7f490d491000-7f490d49a000 r-xp 00000000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d49a000-7f490d69a000 ---p 00009000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69a000-7f490d69b000 r--p 00009000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69b000-7f490d69c000 rw-p 0000a000 08:01 1051244                    /lib/libcrypt-2.12.1.so
7f490d69c000-7f490d6ca000 rw-p 00000000 00:00 0 
7f490d6ca000-7f490d6e2000 r-xp 00000000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d6e2000-7f490d8e1000 ---p 00018000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e1000-7f490d8e2000 r--p 00017000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e2000-7f490d8e3000 rw-p 00018000 08:01 1051256                    /lib/libpthread-2.12.1.so
7f490d8e3000-7f490d8e7000 rw-p 00000000 00:00 0 
7f490d8e7000-7f490da61000 r-xp 00000000 08:01 1048743                    /lib/libc-2.12.1.so
7f490da61000-7f490dc60000 ---p 0017a000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc60000-7f490dc64000 r--p 00179000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc64000-7f490dc65000 rw-p 0017d000 08:01 1048743                    /lib/libc-2.12.1.so
7f490dc65000-7f490dc6a000 rw-p 00000000 00:00 0 
7f490dc6a000-7f490dc7f000 r-xp 00000000 08:01 1048655                    /lib/libgcc_s.so.1
7f490dc7f000-7f490de7e000 ---p 00015000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de7e000-7f490de7f000 r--p 00014000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de7f000-7f490de80000 rw-p 00015000 08:01 1048655                    /lib/libgcc_s.so.1
7f490de80000-7f490df02000 r-xp 00000000 08:01 1051246                    /lib/libm-2.12.1.so
7f490df02000-7f490e101000 ---p 00082000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e101000-7f490e102000 r--p 00081000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e102000-7f490e103000 rw-p 00082000 08:01 1051246                    /lib/libm-2.12.1.so
7f490e103000-7f490e1eb000 r-xp 00000000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e1eb000-7f490e3ea000 ---p 000e8000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3ea000-7f490e3f2000 r--p 000e7000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3f2000-7f490e3f4000 rw-p 000ef000 08:01 4853329                    /usr/lib/libstdc++.so.6.0.14
7f490e3f4000-7f490e409000 rw-p 00000000 00:00 0 
7f490e409000-7f490e5c7000 r-xp 00000000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e5c7000-7f490e7c7000 ---p 001be000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e7c7000-7f490e7cc000 r--p 001be000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e7cc000-7f490e816000 rw-p 001c3000 08:01 4851315                    /usr/lib/libmysqlclient.so.16.0.0
7f490e816000-7f490e817000 rw-p 00000000 00:00 0 
7f490e817000-7f490e837000 r-xp 00000000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea15000-7f490ea1c000 rw-p 00000000 00:00 0 
7f490ea33000-7f490ea37000 rw-p 00000000 00:00 0 
7f490ea37000-7f490ea38000 r--p 00020000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea38000-7f490ea39000 rw-p 00021000 08:01 1048597                    /lib/ld-2.12.1.so
7f490ea39000-7f490ea3a000 rw-p 00000000 00:00 0 
7fffb85b9000-7fffb85da000 rw-p 00000000 00:00 0                          [stack]
7fffb85ff000-7fffb8600000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
Josh
fuente
1
Un punto y coma faltante me provocó este error.
atzol

Respuestas:

105

Significa que tiene un error de memoria. Puede estar intentando con freeun puntero que no fue asignado por malloc(o deleteun objeto que no fue creado por new) o puede estar intentando free/ deletetal objeto más de una vez. Es posible que esté desbordando un búfer o escribiendo en la memoria en la que no debería escribir, lo que provoca daños en el montón.

Cualquier cantidad de errores de programación puede causar este problema. Necesita usar un depurador, obtener un seguimiento y ver qué está haciendo su programa cuando ocurre el error. Si eso falla y determina que ha corrompido el montón en algún momento anterior, es posible que deba realizar una depuración dolorosa (puede que no sea demasiado doloroso si el proyecto es lo suficientemente pequeño como para poder abordarlo pieza por pieza).

James McNellis
fuente
37
Herramientas como valgrind son muy útiles para encontrar el origen de este tipo de errores. Solo asegúrese de compilar con símbolos de depuración.
Daniel Gallagher
3
FYI: Me ha pasado esto después de cambiar el tamaño de un std :: vector <> y no era lo suficientemente grande.
Adam27X
1
De Verdad? Tiene un problema con free () cuando el vector no era lo suficientemente grande. Al menos, preocúpese de leer la pregunta primero.
gyan
21

Encontré el mismo problema, aunque no hice ninguna asignación de memoria dinámica en mi programa, pero estaba accediendo al índice de un vector sin asignarle memoria. Entonces, si es el mismo caso, mejor asigne algo de memoria usando resize()y luego acceda a elementos vectoriales.

vvs14
fuente
7

Necesitamos el código, pero normalmente aparece cuando intenta free()memorizar desde un puntero que no está asignado. Esto sucede a menudo cuando te estás liberando dos veces.

orlp
fuente
6

Si está intentando asignar espacio para una matriz de punteros, como

char** my_array_of_strings;  // or some array of pointers such as int** or even void**

entonces deberá considerar el tamaño de la palabra (8 bytes en un sistema de 64 bits, 4 bytes en un sistema de 32 bits) al asignar espacio para n punteros. El tamaño de un puntero es el mismo que el tamaño de su palabra.

Entonces, si bien es posible que desee asignar espacio para n punteros, en realidad necesitará n veces 8 o 4 (para sistemas de 64 bits o 32 bits, respectivamente)

Para evitar desbordar su memoria asignada para n elementos de 8 bytes:

my_array_of_strings = (char**) malloc( n * 8 );  // for 64-bit systems
my_array_of_strings = (char**) malloc( n * 4 );  // for 32-bit systems

Esto devolverá un bloque de n punteros, cada uno de los cuales consta de 8 bytes (o 4 bytes si está utilizando un sistema de 32 bits)

Me he dado cuenta de que Linux te permitirá usar todos los n punteros cuando no hayas compensado el tamaño de la palabra, pero cuando intentas liberar esa memoria, se da cuenta de su error y emite ese error bastante desagradable. Y es malo, cuando se desborda la memoria asignada, muchos problemas de seguridad acechan.

Jorge
fuente
2
Podemos hacer que el mismo código sea genérico para cualquier sistema en lugar de codificar 4 u 8 bytes usando sizeof(char*).
Ben G.
No usar el sizeofoperador cuando se usa malloc es realmente solo buscar problemas. IIRC, el estándar, garantiza el tamaño de un carácter, pero casi todo lo demás depende de la ISA, por lo que es mejor que lo use en sizeoftodas partes.
ajxs
1

Encontré una situación en la que el código eludía la API de STL y escribía en la matriz de manera insegura cuando alguien lo cambiaba de tamaño. Agregar la afirmación aquí lo atrapó:

void Logo::add(const QVector3D &v, const QVector3D &n)
{
 GLfloat *p = m_data.data() + m_count;
 *p++ = v.x();
 *p++ = v.y();
 *p++ = v.z();
 *p++ = n.x();
 *p++ = n.y();
 *p++ = n.z();
 m_count += 6;
 Q_ASSERT( m_count <= m_data.size() );
}
peter karasev
fuente
1

Encontré un error similar. Fue un error de novato cometido a toda prisa. Matriz de enteros sin declarar el tamaño int a [] y luego intentar acceder a ella. El compilador de C ++ debería haber detectado este error fácilmente si estuviera en main. Sin embargo, dado que esta matriz int particular se declaró dentro de un objeto, se estaba creando al mismo tiempo que mi objeto (se estaban creando muchos objetos) y el compilador arrojaba un error libre (): tamaño siguiente no válido (normal). Pensé en 2 explicaciones para esto (por favor, infórmeme si alguien sabe más): 1.) Esto resultó en que se le asignara una memoria aleatoria, pero como esto no era accesible, estaba liberando toda la memoria del montón solo tratando de encontrar este int. 2.) La memoria requerida por él era prácticamente infinita para un programa y asignarla estaba liberando toda la otra memoria.

Un simple:

    int* a;
    class foo{ 
    foo(){
       for(i=0;i<n;i++)
           a=new int[i];
     }

Resuelve el problema. Pero tomó mucho tiempo tratar de depurar esto porque el compilador no pudo encontrar "realmente" el error.

Arkantos
fuente