Lỗi: free (): kích thước tiếp theo không hợp lệ (nhanh):


90

Tôi nhận được lỗi kỳ lạ này là gì? Tôi đang biên dịch C ++ bằng g ++ trên Ubuntu 10.10. Nó bật lên ngẫu nhiên khi tôi chạy tệp thực thi (có thể 2 lần trong 8 giờ, với 10 lần biên dịch một giờ). Tuy nhiên, nếu tôi làm sạch và biên dịch lại, nó sẽ biến mất hầu hết thời gian.

*** 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
Một dấu chấm phẩy bị thiếu gây ra lỗi này cho tôi.
atzol

Câu trả lời:


105

Có nghĩa là bạn bị lỗi bộ nhớ. Bạn có thể đang cố đến freemột con trỏ không được cấp phát bởi malloc(hoặc deletemột đối tượng không được tạo bởi new) hoặc bạn có thể đang cố gắng free/ deletemột đối tượng như vậy nhiều lần. Bạn có thể làm tràn bộ đệm hoặc ghi vào bộ nhớ mà bạn không nên ghi vào đó, gây ra hỏng heap.

Bất kỳ số lỗi lập trình nào cũng có thể gây ra sự cố này. Bạn cần sử dụng trình gỡ lỗi, lấy dấu vết và xem chương trình của bạn đang làm gì khi lỗi xảy ra. Nếu điều đó không thành công và bạn xác định rằng bạn đã làm hỏng heap tại một số thời điểm trước đó, bạn có thể gặp phải một số gỡ lỗi khó khăn (có thể không quá đau nếu dự án đủ nhỏ để bạn có thể giải quyết từng phần một).


37
Các công cụ như valgrind rất hữu ích khi tìm ra nguồn gốc của các loại lỗi này. Chỉ cần đảm bảo rằng bạn biên dịch với các ký hiệu gỡ lỗi.
Daniel Gallagher

3
FYI: Tôi đã có điều này xảy ra sau khi tôi thay đổi kích thước một std :: vector <> và nó không đủ lớn.
Adam27X

1
Có thật không? Bạn gặp sự cố với free () khi vectơ không đủ lớn. Ít nhất hãy quan tâm đọc câu hỏi trước.
gyan

21

Tôi gặp phải vấn đề tương tự, mặc dù tôi không thực hiện bất kỳ phân bổ bộ nhớ động nào trong chương trình của mình, nhưng tôi đang truy cập chỉ mục của một vectơ mà không cấp phát bộ nhớ cho nó. Vì vậy, nếu trường hợp tương tự, tốt hơn nên cấp phát một số bộ nhớ bằng cách sử dụng resize()và sau đó truy cập các phần tử vectơ.


7

Chúng tôi cần mã, nhưng mã đó thường bật lên khi bạn cố gắng free()bộ nhớ từ một con trỏ không được cấp phát. Điều này thường xảy ra khi bạn giải phóng hai lần.


6

Nếu bạn đang cố gắng phân bổ không gian cho một mảng con trỏ, chẳng hạn như

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

thì bạn sẽ cần phải xem xét kích thước từ (8 byte trong hệ thống 64 bit, 4 byte trong hệ thống 32 bit) khi cấp phát không gian cho n con trỏ. Kích thước của một con trỏ giống với kích thước từ của bạn.

Vì vậy, trong khi bạn có thể muốn cấp phát không gian cho n con trỏ, bạn thực sự sẽ cần n lần 8 hoặc 4 (đối với hệ thống 64 bit hoặc 32 bit, tương ứng)

Để tránh làm tràn bộ nhớ được cấp phát của bạn cho n phần tử 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

Điều này sẽ trả về một khối n con trỏ, mỗi con trỏ bao gồm 8 byte (hoặc 4 byte nếu bạn đang sử dụng hệ thống 32 bit)

Tôi đã nhận thấy rằng Linux sẽ cho phép bạn sử dụng tất cả n con trỏ khi bạn chưa bù cho kích thước từ, nhưng khi bạn cố gắng giải phóng bộ nhớ đó, nó nhận ra lỗi của mình và đưa ra lỗi khá khó chịu đó. Và đó là một điều tồi tệ, khi bạn làm tràn bộ nhớ được cấp phát, nhiều vấn đề bảo mật đang nằm chờ.


2
Chúng tôi có thể tạo cùng một mã chung cho bất kỳ hệ thống nào bằng cách sử dụng mã cứng 4 hoặc 8 byte sizeof(char*).
Ben G.

Không sử dụng sizeoftoán tử khi sử dụng malloc thực sự chỉ là yêu cầu rắc rối. IIRC tiêu chuẩn đảm bảo kích thước của một ký tự, nhưng hầu hết mọi thứ khác đều phụ thuộc vào ISA, vì vậy tốt nhất bạn nên sử dụng sizeofở mọi nơi.
ajxs

1

Tôi đã gặp phải một tình huống như vậy trong đó mã đang phá vỡ api của STL và ghi vào mảng một cách không an toàn khi ai đó thay đổi kích thước nó. Thêm khẳng định ở đây đã bắt được nó:

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

Tôi gặp một lỗi tương tự. Đó là một sai lầm noob được thực hiện một cách vội vàng. Mảng số nguyên mà không khai báo kích thước int a [] thì cố gắng truy cập nó. Trình biên dịch C ++ lẽ ra phải gặp lỗi dễ dàng như vậy nếu nó nằm trong main. Tuy nhiên, vì mảng int cụ thể này đã được khai báo bên trong một đối tượng, nó đang được tạo cùng lúc với đối tượng của tôi (nhiều đối tượng đang được tạo) và trình biên dịch đang gặp lỗi free (): không hợp lệ kích thước tiếp theo (bình thường). Tôi đã nghĩ ra 2 cách giải thích cho điều này (vui lòng khai sáng cho tôi nếu có ai biết thêm): 1.) Điều này dẫn đến một số bộ nhớ ngẫu nhiên được gán cho nó nhưng vì không thể truy cập được nên nó giải phóng tất cả bộ nhớ heap khác chỉ đang cố gắng tìm int này. 2.) Bộ nhớ mà nó yêu cầu thực tế là vô hạn đối với một chương trình và để gán nó, nó đang giải phóng tất cả các bộ nhớ khác.

Một đơn giản:

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

Đã giải quyết vấn đề. Nhưng phải mất rất nhiều thời gian để gỡ lỗi điều này vì trình biên dịch không thể "thực sự" tìm ra lỗi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.