Hata: ücretsiz (): sonraki boyut geçersiz (hızlı):


91

Aldığım bu garip hata nedir? Ubuntu 10.10 üzerinde g ++ kullanarak C ++ derliyorum. Yürütülebilir dosyayı çalıştırdığımda rasgele çıkıyor (belki 8 saatte 2 kez, saatte 10 derleme ile). Ancak, temizler ve yeniden derlersem çoğu zaman kaybolur.

*** 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
Eksik bir noktalı virgül bu hataya neden oldu.
atzol

Yanıtlar:


108

Bu, bir hafıza hatanız olduğu anlamına gelir. Sen çalışıyor olabilirsiniz freetarafından tahsis edilmemiştir bir işaretçi malloc(veya deletetarafından oluşturulmamış bir nesne new) veya çalışıyor olabilirsiniz free/ deletedefadan fazla böyle bir nesne. Bir arabelleği taşıyor veya başka bir şekilde yazmamanız gereken belleğe yazarak yığın bozulmasına neden olabilirsiniz.

Herhangi bir sayıda programlama hatası bu soruna neden olabilir. Bir hata ayıklayıcı kullanmanız, geri izleme almanız ve hata oluştuğunda programınızın ne yaptığını görmeniz gerekir. Bu başarısız olursa ve yığını daha önceki bir noktada bozduğunuzu belirlerseniz, bazı acı verici hata ayıklama işlemlerinde bulunabilirsiniz (proje, parça parça üstesinden gelebileceğiniz kadar küçükse çok acı verici olmayabilir).


37
Valgrind gibi araçlar, bu tür hataların kaynağını bulmada çok faydalıdır. Sadece hata ayıklama sembolleriyle derlediğinizden emin olun.
Daniel Gallagher

3
Bilginize: Bu, bir std :: vektörü <> yeniden boyutlandırdıktan sonra oldu ve yeterince büyük değildi.
Adam27X

1
Gerçekten mi? Vektör yeterince büyük olmadığında free () ile ilgili bir sorununuz var. En azından önce soruyu okumaya özen gösterin.
gyan

22

Programımda dinamik bellek ayırma yapmasam da aynı sorunla karşılaştım, ancak bir vektörün dizinine bellek ayırmadan erişiyordum. Öyleyse, aynı durum söz konusuysa, resize()vektör öğelerini kullanarak biraz bellek ayırın ve sonra bunlara erişin.


7

Koda ihtiyacımız var, ancak bu genellikle free()tahsis edilmemiş bir işaretçiden bellek almaya çalıştığınızda ortaya çıkıyor . Bu genellikle iki kez serbest kaldığınızda olur.


6

Bir dizi işaretçi için alan ayırmaya çalışıyorsanız, örneğin

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

o zaman n işaretçi için yer ayırırken kelime boyutunu (64-bit sistemde 8 bayt, 32-bit sistemde 4 bayt) dikkate almanız gerekecektir. Bir işaretçinin boyutu, kelime boyutunuzla aynıdır.

Dolayısıyla, n işaretçi için alan ayırmak isteyebilirsiniz, ancak aslında n kere 8 veya 4'e ihtiyacınız olacak (sırasıyla 64-bit veya 32-bit sistemler için)

Ayrılan belleğinizin 8 baytlık n öğe için taşmasını önlemek için:

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

Bu, her biri 8 bayttan (veya 32 bit sistem kullanıyorsanız 4 bayt) oluşan n işaretçi bloğu döndürür.

Fark ettim ki Linux, kelime boyutunu telafi etmediğinizde tüm n işaretçileri kullanmanıza izin verir, ancak bu hafızayı boşaltmaya çalıştığınızda, hatasını anlar ve oldukça kötü bir hata verir. Ve bu kötü bir durumdur, ayrılan hafızayı aştığınızda, birçok güvenlik sorunu bekler.


3
4 veya 8 bayt kullanarak kod yazmak yerine herhangi bir sistem için aynı kodu jenerik yapabiliriz sizeof(char*).
Ben G.

Malloc kullanırken sizeofoperatörü kullanmamak gerçekten sadece sorun istemektir. IIRC standardı, bir karakterin boyutunu garanti eder, ancak hemen hemen her şey ISA'ya bağlıdır, bu nedenle sizeofher yerde kullanmanız gerçekten en iyisidir .
ajxs

1

Kodun STL'nin api'sini atlattığı ve birisi yeniden boyutlandırdığında diziye güvenli bir şekilde yazmadığı böyle bir durumla karşılaştım. İddiayı buraya eklemek onu yakaladı:

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

Benzer bir hatayla karşılaştım. Aceleyle yapılan bir noob hatasıydı. İnt a [] boyutunu bildirmeden ve sonra erişmeye çalışmadan tamsayı dizisi. C ++ derleyicisi, ana hataysa böyle bir hatayı kolayca yakalamalıydı. Bununla birlikte, bu belirli int dizisi bir nesnenin içinde bildirildiğinden, benim nesnemle aynı anda yaratılıyordu (birçok nesne yaratılıyordu) ve derleyici bir free (): geçersiz sonraki boyut (normal) hatası atıyordu. Bunun için 2 açıklama düşündüm (lütfen daha fazlasını bilen varsa beni aydınlatın): 1.) Bu, ona rastgele bir bellek atanmasıyla sonuçlandı, ancak bu erişilebilir olmadığından, diğer tüm yığın hafızasını serbest bırakmaya çalışıyordu. bu int. 2.) Bir program için gerekli olan bellek pratikte sonsuzdu ve bunu atamak için diğer tüm belleği serbest bırakıyordu.

Basit:

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

Sorunu çözdüm. Ancak bu hatayı gidermeye çalışmak çok zaman aldı çünkü derleyici hatayı "gerçekten" bulamadı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.