Помилка: безкоштовно (): недійсний наступний розмір (швидко):


90

Що це за дивна помилка, яку я отримую? Я компілюю 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

Відповіді:


105

Це означає, що у вас є помилка пам’яті. Можливо, ви намагаєтесь freeотримати вказівник, який не був призначений malloc(або deleteоб’єкт, який не був створений new), або ви намагаєтесь free/ deleteтакий об’єкт кілька разів. Можливо, ви переповнені буфером або іншим способом записуєте в пам’ять, куди не слід писати, спричиняючи пошкодження купи.

Будь-яка кількість помилок програмування може спричинити цю проблему. Вам потрібно скористатися налагоджувачем, отримати зворотну трасування і подивитися, що робить ваша програма, коли виникає помилка. Якщо це не вдається, і ви визначили, що пошкодили купу в якийсь попередній момент часу, можливо, вас чекає болісна налагодження (це може бути не надто боляче, якщо проект досить малий, щоб ви могли вирішувати його поштучно).


37
Такі інструменти, як valgrind, дуже корисні при пошуку джерела таких типів помилок. Просто переконайтеся, що ви компілюєте із символами налагодження.
Даніель Галлахер,

3
FYI: У мене це сталося після того, як я змінив розмір std :: vector <>, і він був недостатньо великим.
Adam27X

1
Справді? Ви отримали проблему з free (), коли вектор був недостатньо великий. Принаймні, обережно, щоб спочатку прочитати питання.
гьян

21

Я зіткнувся з тією ж проблемою, хоча я не робив жодного динамічного розподілу пам'яті в своїй програмі, але я отримував доступ до векторного індексу, не виділяючи для нього пам'ять. Отже, якщо той самий випадок, краще виділити трохи пам'яті, використовуючи, 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

Це поверне блок з n покажчиків, кожен із 8 байт (або 4 байти, якщо ви використовуєте 32-бітну систему)

Я помітив, що Linux дозволить вам використовувати всі n покажчиків, коли ви не компенсуєте розмір слова, але коли ви намагаєтеся звільнити цю пам'ять, він усвідомлює свою помилку і видає цю досить неприємну помилку. І це погано, коли при переповненні виділеної пам’яті багато проблем безпеки чекають.


2
Ми можемо зробити один і той же код загальним для будь-якої системи, замість жорсткого кодування 4 або 8 байт, використовуючи sizeof(char*).
Бен Г.

Не використання 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

Я зіткнувся з подібною помилкою. Це була помилка нуба, зроблена поспіхом. Ціле масив, не оголошуючи розмір int a [], а потім намагаючись отримати до нього доступ. Компілятор С ++ повинен був легко вловити таку помилку, якби вона була в основному. Однак оскільки цей конкретний масив int був оголошений всередині об'єкта, він створювався одночасно з моїм об'єктом (створювалося багато об'єктів), а компілятор видавав помилку free (): недійсний наступний розмір (нормальний). Я придумав 2 пояснення цього (будь ласка, просвіти мене, якщо хтось знає більше): 1.) Це призвело до того, що йому було призначено якусь випадкову пам'ять, але оскільки це було недоступно, це звільнило всю іншу кучу пам'яті, просто намагаючись знайти цей інт. 2.) Пам'ять, необхідна їй, була практично нескінченною для програми, і для її призначення вона звільняла всю іншу пам'ять.

Просте:

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

Вирішив проблему. Але це займало багато часу, намагаючись налагодити це, оскільки компілятор не зміг "справді" знайти помилку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.