Erreur: gratuit (): taille suivante non valide (rapide):

90

Quelle est cette erreur étrange que j'obtiens? Je compile C ++ en utilisant g ++ sur Ubuntu 10.10. Il apparaît au hasard lorsque je lance l'exécutable (peut-être 2 fois en 8 heures, avec 10 compilations par heure). Cependant, si je nettoie et recompile, il disparaît la plupart du temps.

*** 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
la source
1
Un point-virgule manquant a causé cette erreur pour moi.
atzol

Réponses:

105

Cela signifie que vous avez une erreur de mémoire. Vous pouvez essayer d' freeun pointeur qui n'a pas été affecté par malloc(ou deleteun objet qui n'a pas été créé par new) ou vous pouvez essayer de free/ deleteun tel objet plus d'une fois. Vous pouvez déborder une mémoire tampon ou écrire dans la mémoire dans laquelle vous ne devriez pas écrire, ce qui entraîne une corruption du tas.

N'importe quel nombre d'erreurs de programmation peut provoquer ce problème. Vous devez utiliser un débogueur, obtenir une trace arrière et voir ce que fait votre programme lorsque l'erreur se produit. Si cela échoue et que vous déterminez que vous avez corrompu le tas à un moment donné, vous pouvez être dans un débogage douloureux (cela peut ne pas être trop douloureux si le projet est suffisamment petit pour que vous puissiez le résoudre pièce par pièce).

James McNellis
la source
37
Des outils comme valgrind sont très utiles pour trouver la source de ces types d'erreurs. Assurez-vous simplement de compiler avec des symboles de débogage.
Daniel Gallagher
3
FYI: Cela s'est produit après avoir redimensionné un std :: vector <> et il n'était pas assez grand.
Adam27X
1
Vraiment? Vous avez un problème avec free () lorsque le vecteur n'était pas assez grand. Au moins, prenez soin de lire la question en premier.
gyan le
21

J'ai rencontré le même problème, même si je n'ai pas fait d'allocation de mémoire dynamique dans mon programme, mais j'accédais à l'index d'un vecteur sans y allouer de mémoire. Donc, dans le même cas, mieux allouer de la mémoire en utilisant resize()puis accéder aux éléments vectoriels.

vvs14
la source
7

Nous avons besoin du code, mais cela apparaît généralement lorsque vous essayez de free()mémoire à partir d'un pointeur qui n'est pas alloué. Cela se produit souvent lorsque vous vous libérez deux fois.

orlp
la source
6

Si vous essayez d'allouer de l'espace pour un tableau de pointeurs, tel que

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

alors vous devrez tenir compte de la taille des mots (8 octets dans un système 64 bits, 4 octets dans un système 32 bits) lors de l'allocation d'espace pour n pointeurs. La taille d'un pointeur est la même que celle de votre mot.

Ainsi, même si vous souhaitez allouer de l'espace pour n pointeurs, vous allez en fait avoir besoin de n fois 8 ou 4 (pour les systèmes 64 bits ou 32 bits, respectivement)

Pour éviter de surcharger la mémoire allouée pour n éléments de 8 octets:

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

Cela renverra un bloc de n pointeurs, chacun composé de 8 octets (ou 4 octets si vous utilisez un système 32 bits)

J'ai remarqué que Linux vous permettra d'utiliser tous les n pointeurs lorsque vous n'avez pas compensé la taille des mots, mais lorsque vous essayez de libérer cette mémoire, il réalise son erreur et donne cette erreur plutôt désagréable. Et c'est une mauvaise, lorsque vous dépassez la mémoire allouée, de nombreux problèmes de sécurité vous attendent.

George
la source
2
Nous pouvons rendre le même code générique pour n'importe quel système au lieu de coder en dur 4 ou 8 octets en utilisant sizeof(char*).
Ben G.
Ne pas utiliser l' sizeofopérateur lors de l'utilisation de malloc ne demande que des problèmes. La norme IIRC garantit la taille d'un caractère, mais à peu près tout le reste dépend de l'ISA, il vaut donc mieux l'utiliser sizeofpartout.
ajxs
1

J'ai rencontré une telle situation où le code contournait l'API de STL et écrivait dans le tableau de manière non sécurisée lorsque quelqu'un le redimensionnait. L'ajout de l'affirmation ici l'a attrapé:

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
la source
1

J'ai rencontré une erreur similaire. C'était une erreur noob faite à la hâte. Tableau d'entiers sans déclarer size int a [] puis essayer d'y accéder. Le compilateur C ++ aurait dû intercepter facilement une telle erreur s'il était dans main. Cependant, comme ce tableau int particulier a été déclaré à l'intérieur d'un objet, il était créé en même temps que mon objet (de nombreux objets étaient en cours de création) et le compilateur lançait une erreur free (): invalid next size (normal). J'ai pensé à 2 explications à cela (veuillez m'éclairer si quelqu'un en sait plus): 1.) Cela a abouti à l'attribution d'une mémoire aléatoire, mais comme ce n'était pas accessible, cela libérait toute la mémoire du tas en essayant simplement de trouver cet int. 2.) La mémoire requise par celui-ci était pratiquement infinie pour un programme et l'assigner cela libérait toute autre mémoire.

Un simple:

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

Résolu le problème. Mais il a fallu beaucoup de temps pour essayer de déboguer ceci parce que le compilateur ne pouvait pas "vraiment" trouver l'erreur.

Arkantos
la source