Подтвердить что ты не робот

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

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

Ответ 1

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

Я столкнулся с подобной ошибкой. Это была ошибка, сделанная в спешке. Целый массив без объявления размера int a [], затем пытается получить к нему доступ. Компилятор С++ должен был легко поймать такую ​​ошибку, если бы это было в основном. Однако, поскольку этот конкретный массив 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];
     }

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

Ответ 5

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

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

Ответ 6

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

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() );
}