Ошибка: бесплатно (): недопустимый следующий размер (быстро):

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

Ответы:

108

Это означает, что у вас ошибка памяти. Возможно, вы пытаетесь freeиспользовать указатель, который не был выделен malloc(или deleteобъект, который не был создан new), или вы можете пытаться free/ использовать deleteтакой объект более одного раза. Возможно, вы переполняете буфер или иным образом выполняете запись в память, в которую не должны писать, что вызывает повреждение кучи.

Эту проблему может вызвать любое количество ошибок программирования. Вам нужно использовать отладчик, получить обратную трассировку и посмотреть, что делает ваша программа при возникновении ошибки. Если это не удастся и вы определите, что повредили кучу в какой-то предыдущий момент времени, вам может грозить болезненная отладка (это может быть не слишком болезненно, если проект достаточно мал, чтобы вы могли решать его по частям).

Джеймс МакНеллис
источник
37
Такие инструменты, как valgrind, очень полезны при поиске источника таких ошибок. Просто убедитесь, что вы компилируете с отладочными символами.
Дэниел Галлахер
3
К вашему сведению: у меня это случилось после того, как я изменил размер std :: vector <>, и он был недостаточно большим.
Adam27X
1
В самом деле? У вас возникла проблема с free (), когда вектор был недостаточно большим. По крайней мере, сначала прочтите вопрос.
gyan
22

Я столкнулся с той же проблемой, хотя в своей программе я не выделял динамической памяти, но обращался к индексу вектора, не выделяя для него память. Итак, в том же случае лучше выделить некоторую память, используя, resize()а затем обращаться к элементам вектора.

vvs14
источник
7

Нам нужен код, но он обычно всплывает, когда вы пытаетесь получить доступ к free()памяти из нераспределенного указателя. Это часто случается, когда вы освобождаетесь дважды.

orlp
источник
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 указателей, если вы не компенсировали размер слова, но когда вы пытаетесь освободить эту память, он понимает свою ошибку и выдает эту довольно неприятную ошибку. И это плохо, когда вы переполняете выделенную память, подстерегает множество проблем с безопасностью.

Джордж
источник
3
Мы можем сделать один и тот же код универсальным для любой системы, вместо жесткого кодирования 4 или 8 байтов, используя sizeof(char*).
Бен Г.
Отказ от использования sizeofоператора при использовании malloc на самом деле вызывает проблемы. Стандарт IIRC гарантирует размер символа, но все остальное зависит от ISA, так что лучше всего использовать sizeofвезде.
ajxs
1

Я столкнулся с такой ситуацией, когда код обходил api STL и небезопасно записывал в массив, когда кто-то его изменял. Добавление assert здесь поймало его:

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 [] и попыток доступа к нему. Компилятор C ++ должен был бы легко уловить такую ​​ошибку, если бы она была в main. Однако, поскольку этот конкретный массив int был объявлен внутри объекта, он создавался одновременно с моим объектом (создавалось много объектов), а компилятор выдавал ошибку free (): invalid next size (normal). Я придумал два объяснения этого (пожалуйста, просветите меня, если кто-нибудь знает больше): 1.) Это привело к тому, что ему была назначена некоторая случайная память, но поскольку она была недоступна, она освобождала всю остальную память кучи, просто пытаясь найти этот int. 2.) Требуемая память была практически бесконечной для программы, и для ее назначения освобождалась вся остальная память.

Просто:

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

Решил проблему. Но на то, чтобы отладить это, потребовалось много времени, потому что компилятор не смог «действительно» найти ошибку.

Аркантос
источник