ข้อผิดพลาด: ฟรี (): ขนาดถัดไปไม่ถูกต้อง (เร็ว):


91

ข้อผิดพลาดแปลก ๆ ที่ฉันได้รับคืออะไร? ฉันกำลังรวบรวม C ++ โดยใช้ g ++ บน Ubuntu 10.10 มันจะปรากฏขึ้นแบบสุ่มเมื่อฉันเรียกใช้ไฟล์ปฏิบัติการ (อาจจะ 2 ครั้งใน 8 ชั่วโมงโดยมีการคอมไพล์ 10 ครั้งต่อชั่วโมง) อย่างไรก็ตามหากฉันทำความสะอาดและคอมไพล์ใหม่มันจะหายไปเกือบตลอดเวลา

*** 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
อัฒภาคที่ขาดหายไปทำให้เกิดข้อผิดพลาดนี้สำหรับฉัน
atzol

คำตอบ:


109

หมายความว่าคุณมีข้อผิดพลาดเกี่ยวกับหน่วยความจำ คุณอาจพยายามfreeหาตัวชี้ที่ไม่ได้ถูกจัดสรรโดยmalloc(หรือdeleteวัตถุที่ไม่ได้สร้างขึ้นโดยnew) หรือคุณอาจพยายามfree/ deleteวัตถุดังกล่าวมากกว่าหนึ่งครั้ง คุณอาจมีบัฟเฟอร์ล้นหรือเขียนไปยังหน่วยความจำที่คุณไม่ควรเขียนทำให้เกิดความเสียหายของฮีป

ข้อผิดพลาดในการเขียนโปรแกรมจำนวนเท่าใดก็ได้ที่ทำให้เกิดปัญหานี้ คุณต้องใช้ดีบักเกอร์รับ backtrace และดูว่าโปรแกรมของคุณกำลังทำอะไรเมื่อเกิดข้อผิดพลาด หากล้มเหลวและคุณพบว่าคุณได้ทำฮีปเสียหายในช่วงเวลาก่อนหน้านี้คุณอาจต้องเข้ารับการแก้ไขจุดบกพร่องที่เจ็บปวด (อาจไม่เจ็บปวดเกินไปหากโครงการมีขนาดเล็กพอที่คุณสามารถจัดการทีละชิ้นได้)


37
เครื่องมือเช่น valgrind มีประโยชน์มากเมื่อค้นหาแหล่งที่มาของข้อผิดพลาดประเภทนี้ ตรวจสอบให้แน่ใจว่าคุณรวบรวมด้วยสัญลักษณ์การดีบัก
Daniel Gallagher

3
FYI: ฉันเคยเกิดเหตุการณ์นี้ขึ้นหลังจากที่ฉันปรับขนาด std :: vector <> และมันก็ไม่ใหญ่พอ
Adam27X

1
จริงๆ? คุณพบปัญหาเกี่ยวกับ free () เมื่อเวกเตอร์มีขนาดไม่ใหญ่พอ อย่างน้อยใส่ใจอ่านคำถามก่อน
gyan

22

ฉันพบปัญหาเดียวกันแม้ว่าฉันจะไม่ได้ทำการจัดสรรหน่วยความจำแบบไดนามิกในโปรแกรมของฉัน แต่ฉันกำลังเข้าถึงดัชนีของเวกเตอร์โดยไม่ได้จัดสรรหน่วยความจำให้ ดังนั้นหากเป็นกรณีเดียวกันควรจัดสรรหน่วยความจำบางส่วนโดยใช้resize()แล้วเข้าถึงองค์ประกอบเวกเตอร์


7

เราต้องการรหัส แต่มักจะปรากฏขึ้นเมื่อคุณพยายามใช้free()หน่วยความจำจากตัวชี้ที่ไม่ได้รับการจัดสรร สิ่งนี้มักเกิดขึ้นเมื่อคุณปล่อยให้ว่างสองครั้ง


6

หากคุณพยายามจัดสรรพื้นที่สำหรับอาร์เรย์ของพอยน์เตอร์เช่น

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

จากนั้นคุณจะต้องพิจารณาขนาดคำ (8 ไบต์ในระบบ 64 บิต 4 ไบต์ในระบบ 32 บิต) เมื่อจัดสรรพื้นที่สำหรับ n พอยน์เตอร์ ขนาดของตัวชี้จะเท่ากับขนาดคำของคุณ

ดังนั้นในขณะที่คุณอาจต้องการจัดสรรพื้นที่สำหรับ n พอยน์เตอร์คุณจะต้อง n คูณ 8 หรือ 4 (สำหรับระบบ 64 บิตหรือ 32 บิตตามลำดับ)

เพื่อหลีกเลี่ยงไม่ให้หน่วยความจำที่จัดสรรของคุณล้นสำหรับองค์ประกอบ n ขนาด 8 ไบต์:

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

สิ่งนี้จะส่งคืนบล็อกของพอยน์เตอร์แต่ละตัวประกอบด้วย 8 ไบต์ (หรือ 4 ไบต์หากคุณใช้ระบบ 32 บิต)

ฉันสังเกตเห็นว่า Linux จะอนุญาตให้คุณใช้ n พอยน์เตอร์ทั้งหมดเมื่อคุณไม่ได้ชดเชยขนาดคำ แต่เมื่อคุณพยายามปลดปล่อยหน่วยความจำนั้นจะตระหนักถึงความผิดพลาดและให้ข้อผิดพลาดที่ค่อนข้างน่ารังเกียจ และเป็นเรื่องที่ไม่ดีเมื่อคุณจัดสรรหน่วยความจำมากเกินไปปัญหาด้านความปลอดภัยมากมายรออยู่


3
เราสามารถทำให้รหัสเดียวกันทั่วไปกับระบบใด ๆ โดยแทน hardcoding 4 หรือ 8 sizeof(char*)ไบต์ใช้
Ben G.

การไม่ใช้ตัวsizeofดำเนินการเมื่อใช้ malloc เป็นเพียงการขอปัญหา มาตรฐาน IIRC รับประกันขนาดของถ่าน แต่สิ่งอื่น ๆ นั้นขึ้นอยู่กับ ISA ดังนั้นคุณจึงควรใช้sizeofทุกที่อย่างดีที่สุด
ajxs

1

ฉันพบสถานการณ์เช่นนี้ที่โค้ดหลีกเลี่ยง api ของ STL และเขียนไปยังอาร์เรย์อย่างไม่ปลอดภัยเมื่อมีคนปรับขนาด การเพิ่มการยืนยันที่นี่จับได้:

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

ฉันพบข้อผิดพลาดที่คล้ายกัน มันเป็นความผิดพลาดของ noob ที่รีบทำ อาร์เรย์จำนวนเต็มโดยไม่ต้องประกาศขนาด int a [] จากนั้นพยายามเข้าถึง คอมไพเลอร์ C ++ น่าจะพบข้อผิดพลาดดังกล่าวได้ง่ายหากอยู่ในหลัก อย่างไรก็ตามเนื่องจาก int อาร์เรย์เฉพาะนี้ถูกประกาศภายในอ็อบเจ็กต์จึงถูกสร้างขึ้นในเวลาเดียวกันกับอ็อบเจ็กต์ของฉัน (มีการสร้างอ็อบเจ็กต์จำนวนมาก) และคอมไพเลอร์กำลังโยนข้อผิดพลาด free (): invalid next size (normal) ฉันนึกถึงคำอธิบาย 2 ข้อสำหรับสิ่งนี้ (โปรดแจ้งให้ฉันทราบหากมีใครรู้มากกว่านี้): 1. ) สิ่งนี้ส่งผลให้มีการกำหนดหน่วยความจำแบบสุ่มบางส่วนให้กับมัน แต่เนื่องจากสิ่งนี้ไม่สามารถเข้าถึงได้จึงทำให้หน่วยความจำฮีปอื่น ๆ ทั้งหมดว่างเพียงแค่พยายามค้นหา int. นี้ 2. ) หน่วยความจำที่ต้องการโดยมันแทบไม่มีที่สิ้นสุดสำหรับโปรแกรมและการกำหนดสิ่งนี้มันเป็นการเพิ่มหน่วยความจำอื่น ๆ ทั้งหมด

ง่ายๆ:

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

แก้ไขปัญหา แต่ต้องใช้เวลานานในการพยายามดีบักนี้เนื่องจากคอมไพเลอร์ไม่สามารถ "หาข้อผิดพลาด" ได้จริงๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.