Erro: gratuito (): próximo tamanho inválido (rápido):

90

Que erro estranho estou recebendo? Estou compilando C ++ usando g ++ no Ubuntu 10.10. Ele aparece aleatoriamente quando executo o executável (talvez 2 vezes em 8 horas, com 10 compilações por hora). No entanto, se eu limpar e recompilar, ele irá embora na maioria das vezes.

*** 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
Josh
fonte
1
Um ponto-e-vírgula ausente causou esse erro para mim.
atzol

Respostas:

105

Isso significa que você tem um erro de memória. Você pode estar tentando freeacessar um ponteiro que não foi alocado por malloc(ou deleteum objeto que não foi criado por new) ou pode estar tentando free/ deletetal objeto mais de uma vez. Você pode estar sobrecarregando um buffer ou gravando em uma memória na qual não deveria estar gravando, causando corrupção de heap.

Qualquer número de erros de programação pode causar esse problema. Você precisa usar um depurador, obter um backtrace e ver o que seu programa está fazendo quando o erro ocorre. Se isso falhar e você determinar que corrompeu o heap em algum ponto anterior no tempo, poderá sofrer uma depuração dolorosa (pode não ser muito doloroso se o projeto for pequeno o suficiente para que você possa lidar com ele peça por peça).

James McNellis
fonte
37
Ferramentas como o valgrind são muito úteis para encontrar a origem desses tipos de erros. Apenas certifique-se de compilar com símbolos de depuração.
Daniel Gallagher
3
FYI: Isso aconteceu depois de redimensionar um std :: vector <> e não era grande o suficiente.
Adam27X
1
Realmente? Você teve um problema com free () quando o vetor não era grande o suficiente. Ao menos, leia a pergunta primeiro.
gyan
21

Encontrei o mesmo problema, embora não tenha feito nenhuma alocação dinâmica de memória em meu programa, mas estava acessando um índice de vetor sem alocar memória para ele. Portanto, se for o mesmo caso, é melhor alocar um pouco de memória usando resize()e, em seguida, acessar os elementos do vetor.

vvs14
fonte
7

Precisamos do código, mas ele geralmente aparece quando você tenta a free()memória de um ponteiro que não está alocado. Isso geralmente acontece quando você está liberando duas vezes.

orlp
fonte
6

Se você está tentando alocar espaço para uma série de ponteiros, como

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

em seguida, você precisará considerar o tamanho da palavra (8 bytes em um sistema de 64 bits, 4 bytes em um sistema de 32 bits) ao alocar espaço para n ponteiros. O tamanho de um ponteiro é igual ao tamanho da palavra.

Então, embora você possa querer alocar espaço para n ponteiros, na verdade você vai precisar de n vezes 8 ou 4 (para sistemas de 64 ou 32 bits, respectivamente)

Para evitar o estouro de sua memória alocada para n elementos de 8 bytes:

my_array_of_strings = (char**) malloc( n * 8 );  // for 64-bit systems
my_array_of_strings = (char**) malloc( n * 4 );  // for 32-bit systems

Isso retornará um bloco de n ponteiros, cada um consistindo de 8 bytes (ou 4 bytes se você estiver usando um sistema de 32 bits)

Percebi que o Linux permitirá que você use todos os n ponteiros quando você não compensou o tamanho da palavra, mas quando você tenta liberar essa memória, ele percebe seu erro e mostra aquele erro bastante desagradável. E é ruim, quando você transborda a memória alocada, muitos problemas de segurança aguardam.

George
fonte
2
Podemos tornar o mesmo código genérico para qualquer sistema em vez de codificar 4 ou 8 bytes usando sizeof(char*).
Ben G.
Não usar o sizeofoperador ao usar o malloc é apenas pedir problemas. O padrão IIRC garante o tamanho de um char, mas praticamente qualquer outra coisa depende do ISA, então é melhor usá-lo em sizeofqualquer lugar.
ajxs de
1

Eu encontrei uma situação em que o código estava contornando a API do STL e gravando no array de maneira não segura quando alguém o redimensionava. Adicionar a declaração aqui pegou:

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() );
}
Peter Karasev
fonte
1

Eu encontrei um erro semelhante. Foi um erro noob cometido às pressas. Array inteiro sem declarar o tamanho int a [] e então tentar acessá-lo. O compilador C ++ deveria ter detectado esse erro facilmente se estivesse no principal. No entanto, como esse array int específico foi declarado dentro de um objeto, ele estava sendo criado ao mesmo tempo que meu objeto (muitos objetos estavam sendo criados) e o compilador estava lançando um erro free (): invalid next size (normal). Pensei em 2 explicações para isso (por favor, esclareça-me se alguém souber mais): 1.) Isso resultou em alguma memória aleatória sendo atribuída a ele, mas como não estava acessível, estava liberando toda a outra memória heap apenas tentando encontrar este int. 2.) A memória exigida por ele era praticamente infinita para um programa e para atribuí-lo estava liberando todas as outras memórias.

Um simples:

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

Resolveu o problema. Mas demorou muito para tentar depurar isso porque o compilador não conseguiu "realmente" encontrar o erro.

Arkantos
fonte