Fout: free(): ongeldige volgende maat (snel):

Wat is deze vreemde foutmelding die ik krijg? Ik compileer C++ met g++ op Ubuntu 10.10. Het verschijnt willekeurig wanneer ik het uitvoerbare bestand uitvoer (misschien 2 keer in 8 uur, met 10 compilaties per uur). Als ik echter opschon en opnieuw compileer, verdwijnt het meestal.

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

Antwoord 1, autoriteit 100%

Het betekent dat je een geheugenfout hebt. Mogelijk probeert u een aanwijzer freete maken die niet is toegewezen door malloc(of deleteeen object dat niet is gemaakt door new) of u probeert mogelijk meer dan eens een dergelijk object te free/delete. Mogelijk loopt een buffer over of schrijft u op een andere manier naar het geheugen waarnaar u niet zou moeten schrijven, waardoor heapcorruptie wordt veroorzaakt.

Een willekeurig aantal programmeerfouten kan dit probleem veroorzaken. U moet een debugger gebruiken, een backtrace krijgen en zien wat uw programma doet wanneer de fout optreedt. Als dat niet lukt en je vaststelt dat je de hoop op een eerder tijdstip hebt beschadigd, kun je een pijnlijke debugging ondergaan (het is misschien niet zo pijnlijk als het project klein genoeg is om het stukje bij beetje aan te pakken).


Antwoord 2, autoriteit 20%

Ik kwam hetzelfde probleem tegen, ook al heb ik geen dynamische geheugentoewijzing in mijn programma gemaakt, maar ik had toegang tot de index van een vector zonder er geheugen voor toe te wijzen.
Dus in hetzelfde geval kunt u beter wat geheugen toewijzen met resize()en vervolgens toegang krijgen tot vectorelementen.


Antwoord 3, autoriteit 6%

We hebben de code nodig, maar die verschijnt meestal wanneer u free()geheugen probeert te maken van een aanwijzer die niet is toegewezen. Dit gebeurt vaak wanneer je dubbel bevrijdt.


Antwoord 4, autoriteit 5%

Als u ruimte probeert toe te wijzen voor een reeks aanwijzers, zoals

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

dan moet je rekening houden met de woordgrootte (8 bytes in een 64-bits systeem, 4 bytes in een 32-bits systeem) bij het toewijzen van ruimte voor n pointers. De grootte van een aanwijzer is hetzelfde als uw woordgrootte.

Dus hoewel je misschien ruimte wilt toewijzen voor n pointers, heb je in feite n keer 8 of 4 nodig (voor respectievelijk 64-bits of 32-bits systemen)

Om te voorkomen dat uw toegewezen geheugen voor n elementen van 8 bytes overloopt:

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

Dit geeft een blok van n pointers terug, elk bestaande uit 8 bytes (of 4 bytes als je een 32-bits systeem gebruikt)

Ik heb gemerkt dat Linux je toestaat om alle n pointers te gebruiken als je de woordgrootte niet hebt gecompenseerd, maar wanneer je dat geheugen probeert vrij te maken, realiseert het zich zijn fout en geeft het die nogal vervelende fout weer. En het is een slechte, wanneer je toegewezen geheugen overloopt, liggen veel beveiligingsproblemen op de loer.


Antwoord 5

Ik kwam een dergelijke situatie tegen waarbij code de API van STL omzeilde en onveilig naar de array schreef wanneer iemand de grootte ervan aanpaste. Het toevoegen van de bewering hier ving het op:

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

Antwoord 6

Ik ben een soortgelijke fout tegengekomen. Het was een noob fout gemaakt in een haast. Integer array zonder de grootte int a[] te declareren en vervolgens te proberen er toegang toe te krijgen.
De C++-compiler had zo’n fout gemakkelijk moeten opvangen als het in de hoofdmap was. Omdat deze specifieke int-array echter in een object werd gedeclareerd, werd het tegelijkertijd met mijn object gemaakt (er werden veel objecten gemaakt) en de compiler gooide een free(): invalid next size(normal) error.
Ik bedacht hiervoor 2 verklaringen (verlicht me als iemand meer weet):
1.) Dit resulteerde in een willekeurig geheugen dat eraan werd toegewezen, maar omdat dit niet toegankelijk was, maakte het al het andere heap-geheugen vrij dat alleen maar probeerde deze int te vinden.
2.) Het benodigde geheugen was praktisch oneindig voor een programma en om dit toe te wijzen maakte het al het andere geheugen vrij.

Een simpele:

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

Het probleem is opgelost. Maar het kostte veel tijd om dit te debuggen omdat de compiler de fout niet “echt” kon vinden.

Other episodes