Kesalahan: gratis (): ukuran berikutnya tidak valid (cepat):

91

Kesalahan aneh apa yang saya dapatkan ini? Saya mengkompilasi C ++ menggunakan g ++ di Ubuntu 10.10. Itu muncul secara acak ketika saya menjalankan executable (mungkin 2 kali dalam 8 jam, dengan 10 kompilasi satu jam). Namun, jika saya membersihkan dan mengompilasi ulang, itu akan hilang sebagian besar waktu.

*** 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
sumber
1
Titik koma yang hilang menyebabkan kesalahan ini bagi saya.
atzol

Jawaban:

108

Artinya Anda mengalami kesalahan memori. Anda mungkin mencoba ke freepointer yang tidak dialokasikan oleh malloc(atau deleteobjek yang tidak dibuat oleh new) atau Anda mungkin mencoba free/ objek deletesemacam itu lebih dari sekali. Anda mungkin memenuhi buffer atau menulis ke memori yang seharusnya tidak Anda tulis, menyebabkan kerusakan heap.

Sejumlah kesalahan pemrograman dapat menyebabkan masalah ini. Anda perlu menggunakan debugger, mendapatkan pelacakan mundur, dan melihat apa yang dilakukan program Anda saat kesalahan terjadi. Jika gagal dan Anda menentukan bahwa Anda telah merusak heap pada beberapa titik waktu sebelumnya, Anda mungkin mengalami beberapa proses debug yang menyakitkan (mungkin tidak terlalu menyakitkan jika proyeknya cukup kecil sehingga Anda dapat menanganinya sepotong demi sepotong).

James McNellis
sumber
37
Alat seperti valgrind sangat membantu saat menemukan sumber jenis kesalahan ini. Pastikan Anda mengompilasi dengan simbol debugging.
Daniel Gallagher
3
FYI: Saya mengalami ini setelah saya mengubah ukuran std :: vector <> dan itu tidak cukup besar.
Adam27X
1
Betulkah? Anda mendapat masalah dengan free () saat vektor tidak cukup besar. Setidaknya hati-hati untuk membaca pertanyaannya dulu.
gyan
22

Saya mengalami masalah yang sama, meskipun saya tidak membuat alokasi memori dinamis dalam program saya, tetapi saya mengakses indeks vektor tanpa mengalokasikan memori untuk itu. Jadi, jika kasusnya sama, lebih baik alokasikan beberapa memori menggunakan resize()dan kemudian akses elemen vektor.

vvs14
sumber
7

Kami membutuhkan kode, tetapi biasanya muncul ketika Anda mencoba untuk free()mengingat dari pointer yang tidak dialokasikan. Ini sering terjadi saat Anda membebaskan ganda.

orlp
sumber
6

Jika Anda mencoba mengalokasikan ruang untuk array pointer, seperti

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

maka Anda perlu mempertimbangkan ukuran kata (8 byte dalam sistem 64-bit, 4 byte dalam sistem 32-bit) saat mengalokasikan ruang untuk n pointer. Ukuran sebuah pointer sama dengan ukuran kata Anda.

Jadi sementara Anda mungkin ingin mengalokasikan ruang untuk n pointer, Anda sebenarnya akan membutuhkan n kali 8 atau 4 (untuk sistem 64-bit atau 32-bit, masing-masing)

Untuk menghindari meluapnya memori yang dialokasikan untuk n elemen 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

Ini akan mengembalikan satu blok n pointer, masing-masing terdiri dari 8 byte (atau 4 byte jika Anda menggunakan sistem 32-bit)

Saya telah memperhatikan bahwa Linux akan memungkinkan Anda untuk menggunakan semua n petunjuk ketika Anda belum mengkompensasi ukuran kata, tetapi ketika Anda mencoba untuk membebaskan memori itu menyadari kesalahannya dan itu memberikan kesalahan yang agak buruk. Dan itu buruk, ketika Anda meluap memori yang dialokasikan, banyak masalah keamanan menunggu.

George
sumber
3
Kita dapat membuat kode yang sama menjadi umum untuk sistem apapun dengan menggunakan hardcoding 4 atau 8 byte sizeof(char*).
Ben G.
Tidak pake sizeofoperator kalau pake malloc sebenarnya cuma bikin repot. IIRC standar menjamin ukuran sebuah char, tapi hampir semua hal lain yang terserah ISA, jadi Anda benar-benar terbaik menggunakannya di sizeofmana - mana.
ajxs
1

Saya mengalami situasi seperti itu di mana kode menghindari api STL dan menulis ke array dengan tidak aman ketika seseorang mengubah ukurannya. Menambahkan pernyataan di sini menangkapnya:

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
sumber
1

Saya mengalami kesalahan serupa. Itu adalah kesalahan noob yang dilakukan dengan terburu-buru. Array integer tanpa mendeklarasikan ukuran int a [] kemudian mencoba mengaksesnya. Kompiler C ++ seharusnya menangkap kesalahan seperti itu dengan mudah jika berada di main. Namun karena larik int khusus ini dideklarasikan di dalam suatu objek, itu dibuat pada saat yang sama dengan objek saya (banyak objek sedang dibuat) dan kompiler mengeluarkan kesalahan free (): invalid next size (normal). Saya memikirkan 2 penjelasan untuk ini (tolong beri tahu saya jika ada yang tahu lebih banyak): 1.) Ini menghasilkan beberapa memori acak yang ditugaskan padanya tetapi karena ini tidak dapat diakses, itu membebaskan semua memori tumpukan lainnya hanya mencoba untuk menemukan int ini. 2.) Memori yang dibutuhkan olehnya secara praktis tidak terbatas untuk sebuah program dan untuk menetapkan ini, itu membebaskan semua memori lainnya.

Sederhana:

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

Memecahkan masalah. Tetapi memang butuh banyak waktu untuk mencoba men-debug ini karena kompilator tidak dapat "benar-benar" menemukan kesalahan tersebut.

Arkantos
sumber