web-dev-qa-db-fra.com

Erreur: free (): prochaine taille non valide (rapide):

Quelle est cette erreur étrange que je reçois? Je compile C++ en utilisant g ++ sur Ubuntu 10.10. Il apparaît aléatoirement 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
76
Josh

Cela signifie que vous avez une erreur de mémoire. Vous essayez peut-être de free un pointeur qui n’a pas été alloué par malloc (ou delete un objet qui n’a pas été créé par new) ou par vous-même. peut-être essayer de free/delete un tel objet plusieurs fois. Vous pouvez déborder d'un tampon ou écrire d'une autre manière dans la mémoire sur laquelle vous ne devriez pas écrire, provoquant une corruption de tas.

Ce problème peut être dû à un nombre illimité d'erreurs de programmation. Vous devez utiliser un débogueur, obtenir une trace, et voir ce que votre programme fait lorsque l'erreur se produit. Si cela échoue et que vous déterminez que vous avez corrompu le tas à un moment donné dans le passé, vous risquez un débogage pénible (cela ne sera peut-être pas trop douloureux si le projet est suffisamment petit pour que vous puissiez le traiter pièce par pièce).

92
James McNellis

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

17
vvs14

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

6
orlp

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

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

vous devrez ensuite tenir compte de la taille de mot (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 identique à la taille de votre mot.

Ainsi, bien que vous souhaitiez allouer de l'espace pour n pointeurs, vous aurez en fait besoin de n fois 8 ou 4 (pour les systèmes 64 bits ou 32 bits, respectivement).

Pour éviter de saturer votre 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 retournera 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 de Word, mais lorsque vous essayez de libérer cette mémoire, il réalise son erreur et génère une erreur plutôt désagréable. Et c’est un problème grave: lorsque vous surchargez la mémoire allouée, de nombreux problèmes de sécurité vous attendent.

3
george

J'ai rencontré une erreur similaire. C'était une erreur de Noob faite à la hâte. Tableau entier sans déclarer la taille int a [] puis en essayant d'y accéder. Le compilateur C++ aurait dû facilement intercepter une telle erreur si elle était en mode principal. Cependant, puisque ce tableau int particulier a été déclaré dans un objet, il était créé en même temps que mon objet (de nombreux objets étaient en cours de création) et le compilateur renvoyait une erreur free (): invalid next size (normal). J'ai pensé à deux explications à cela (veuillez m'éclairer si quelqu'un en sait plus): 1.) Cela a entraîné l'attribution d'une mémoire aléatoire, mais comme elle n'était pas accessible, elle libérait toute la mémoire supplémentaire en train d'essayer de la trouver. cette int. 2.) La mémoire requise par celle-ci était pratiquement infinie pour un programme et l'affecter 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 résoudre ce problème car le compilateur ne pouvait pas "vraiment" trouver l'erreur.

1
Arkantos

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. Ajouter l'assertion 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() );
}
0
peter karasev