Errore: gratuito (): dimensione successiva non valida (veloce):


90

Qual è questo strano errore che ricevo? Sto compilando C ++ usando g ++ su Ubuntu 10.10. Si apre in modo casuale quando eseguo l'eseguibile (forse 2 volte in 8 ore, con 10 compilazioni all'ora). Tuttavia, se eseguo la pulizia e la ricompilazione, la maggior parte delle volte scompare.

*** 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

1
Un punto e virgola mancante ha causato questo errore per me.
atzol

Risposte:


105

Significa che hai un errore di memoria. Potresti provare a freeun puntatore che non è stato assegnato da malloc(o deleteun oggetto che non è stato creato da new) o potresti provare a free/ deletetale oggetto più di una volta. Potresti sovraccaricare un buffer o scrivere in altro modo nella memoria su cui non dovresti scrivere, causando il danneggiamento dell'heap.

Qualsiasi numero di errori di programmazione può causare questo problema. È necessario utilizzare un debugger, ottenere un backtrace e vedere cosa sta facendo il programma quando si verifica l'errore. Se fallisce e determini di aver danneggiato l'heap in un momento precedente, potresti dover affrontare un doloroso debugging (potrebbe non essere troppo doloroso se il progetto è abbastanza piccolo da poterlo affrontare pezzo per pezzo).


37
Strumenti come valgrind sono molto utili per trovare la fonte di questi tipi di errori. Assicurati solo di compilare con i simboli di debug.
Daniel Gallagher

3
FYI: Ho avuto questo problema dopo aver ridimensionato uno std :: vector <> e non era abbastanza grande.
Adam27X

1
Veramente? Hai avuto un problema con free () quando il vettore non era abbastanza grande. Almeno tieni a leggere prima la domanda.
gyan

21

Ho riscontrato lo stesso problema, anche se non ho effettuato alcuna allocazione dinamica della memoria nel mio programma, ma stavo accedendo all'indice di un vettore senza allocare memoria per esso. Quindi, se lo stesso caso, è meglio allocare un po 'di memoria utilizzando resize()e quindi accedere agli elementi vettoriali.


7

Abbiamo bisogno del codice, ma di solito viene visualizzato quando provi a free()memorizzare da un puntatore non allocato. Questo accade spesso quando stai liberando due volte.


6

Se stai cercando di allocare spazio per una matrice di puntatori, come

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

quindi sarà necessario considerare la dimensione della parola (8 byte in un sistema a 64 bit, 4 byte in un sistema a 32 bit) quando si alloca lo spazio per n puntatori. La dimensione di un puntatore è la stessa della dimensione della parola.

Quindi, anche se potresti voler allocare spazio per n puntatori, in realtà avrai bisogno di n volte 8 o 4 (rispettivamente per sistemi a 64 o 32 bit)

Per evitare di sovraccaricare la memoria allocata per n elementi di 8 byte:

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

Questo restituirà un blocco di n puntatori, ciascuno composto da 8 byte (o 4 byte se stai usando un sistema a 32 bit)

Ho notato che Linux ti permetterà di usare tutti gli n puntatori quando non hai compensato la dimensione della parola, ma quando provi a liberare quella memoria si rende conto del suo errore e dà quell'errore piuttosto sgradevole. Ed è brutto, quando si sovraccarica la memoria allocata, molti problemi di sicurezza sono in agguato.


2
Possiamo rendere lo stesso codice generico per qualsiasi sistema invece di codificare 4 o 8 byte usando sizeof(char*).
Ben G.

Non usare l' sizeofoperatore quando si usa malloc è solo chiedere guai. Lo standard IIRC garantisce le dimensioni di un carattere, ma praticamente tutto il resto dipende dall'ISA, quindi è meglio usarlo sizeofovunque.
ajxs

1

Ho riscontrato una situazione del genere in cui il codice aggirava l'API di STL e scriveva sull'array in modo non sicuro quando qualcuno lo ridimensionava. Aggiungendo l'asserzione qui catturato:

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() );
}

1

Ho riscontrato un errore simile. È stato un errore da noob fatto in fretta. Matrice intera senza dichiarare size int a [] e poi tentare di accedervi. Il compilatore C ++ avrebbe dovuto rilevare facilmente un errore del genere se fosse stato in main. Tuttavia, poiché questo particolare array int è stato dichiarato all'interno di un oggetto, è stato creato contemporaneamente al mio oggetto (sono stati creati molti oggetti) e il compilatore ha lanciato un errore free (): invalid next size (normal). Ho pensato a 2 spiegazioni per questo (per favore illuminami se qualcuno ne sa di più): 1.) Ciò ha comportato l'assegnazione di una memoria casuale ma poiché questo non era accessibile stava liberando tutta la memoria dell'heap solo cercando di trovare questo int. 2.) La memoria da esso richiesta era praticamente infinita per un programma e per assegnarla si liberava tutta la memoria.

Un semplice:

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

Problema risolto. Ma ci è voluto molto tempo per provare a eseguire il debug perché il compilatore non è riuscito a trovare "veramente" l'errore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.