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

Что это за странная ошибка, которую я получаю? Я компилирую 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

7 ответов

Решение

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

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

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

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

Если вы пытаетесь выделить место для массива указателей, таких как

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

Я столкнулся с подобной ошибкой. Это была ошибка нуба, сделанная в спешке. Целочисленный массив без объявления размера int a[] и последующей попытки доступа к нему. Компилятор C++ должен был бы легко обнаружить такую ​​ошибку, если бы она была в main. Однако, поскольку этот конкретный массив int был объявлен внутри объекта, он создавался одновременно с моим объектом (создавалось много объектов), и компилятор выдавал ошибку free(): invalid следующего размера (нормального). Я подумал о двух объяснениях этого (пожалуйста, просветите меня, если кто-то знает больше): 1.) Это привело к тому, что ему была назначена некоторая случайная память, но так как она была недоступна, она освобождала всю остальную память кучи, просто пытаясь найти это инт. 2.) Требуемая им память была практически бесконечной для программы, и для ее выделения она освобождала всю остальную память.

Просто:

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

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

Я столкнулся с такой ситуацией, когда код обходил 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() );
}

Недавно я столкнулся с той же ошибкой в ​​C: free(): неверный следующий размер (быстро).

В моем случае у меня был такой код, в котором я по ошибке выделял размер указателя структуры вместо самой структуры:

      typedef struct {
    ...
} SomeStruct;
SomeStruct *someStruct = malloc(sizeof(SomeStruct*));
...
free(someStruct);

Malloc должен был быть:

      malloc(sizeof(SomeStruct));

Это исправило ошибку. Надеюсь, это поможет кому-то еще.

Другие вопросы по тегам