Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1425 connectés 

  FORUM HardWare.fr
  Programmation
  C

  free(): invalid pointer 0x40318008! [Résolu]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

free(): invalid pointer 0x40318008! [Résolu]

n°867277
darkoli
Le Petit Dinosaure Bleu
Posté le 07-10-2004 à 18:25:26  profilanswer
 

Je ne comprends pas pourquoi la fonction free() considère cette adresse comme invalide. Mais c'est un appel à la fonction malloc() qui me l'a retourné.
 
Dans le programme j'alloue une variable ("ea->lignes" ), de type "lEA*", un pointeur sur une structure. La taille allouée est de 1 372 012 octets (5623 fois la structure) et j'obtiens comme adresse : 0x40318008. Le traitement continue est au moment de libérer la mémoire à l'aide de la fonction free() j'obtiens le message suivant : "free(): invalid pointer 0x40318008!". Le programme se termine normalement. Pendant l'exécution la zone mémoire est bien allouée, je fais des calculs et un affichage et il y a aucun problème.
 
J'ai pensé que je liberais la strcuture plus d'une fois mais ce n'est pas le cas, et j'ai vérifié tout le code. Quand je fais appel à la fonction free() je vérifie que le pointeur n'est pas NULL et après l'appel de la fonction free() je positionne le pointeur à NULL.
 
Est-ce que quelqu'un aurait une explication ?
OS : Linux wh11686 2.4.23 #1 lun déc 29 10:39:32 CET 2003 i686 GNU/Linux
Compilateur : gcc 3.3.4 (Debian 1:3.3.4-6sarge1)
 
La variable ea est déclarée en static dans la fonction nom_de_la_fonction1 qui initialise la structure. La zone mémoire sera allouée dans la fonction nom_de_la_fonction2. La zone mémoire sera finalement liberée dans la fonction nom_de_la_fonction1.
 

(gdb) p ea.lignes
$4 = (lEA *) 0x0
(gdb) watch ea.lignes
Hardware watchpoint 4: ea.lignes
(gdb) c
Continuing.
[...]
Hardware watchpoint 4: ea.lignes
 
Old value = (lEA *) 0x0
New value = (lEA *) 0x40318008
nom_de_la_fonction2 (p1=0x806ac68, p2=0x8081ab8, ea=0x806a900) at nom_du_programme.c:5728
(gdb) p ea->lignes
$5 = (lEA *) 0x40318008
(gdb) p taille
$8 = 1372012
(gdb) c
Continuing.
[...]
1028       if (ea.lignes != NULL) free(ea.lignes);
(gdb) p ea->lignes
$11 = (lEA *) 0x40318008
(gdb) n
1029       ea.lignes=NULL;
(gdb) p ea->lignes
$12 = (lEA *) 0x40318008
(gdb) n
Hardware watchpoint 4: ea.lignes
 
Old value = (lEA *) 0x40318008
New value = (lEA *) 0x0
nom_de_la_fonction1 (p3=0x0, p4=0x0, p5=0, p6=0, p7=0x0, p8=0x0, p2=0x0) at nom_du_programme.c:1030
[...]
(gdb) c
Continuing.
 
Program exited normally.


Message édité par darkoli le 13-10-2004 à 13:57:36

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
mood
Publicité
Posté le 07-10-2004 à 18:25:26  profilanswer
 

n°867280
Taz
bisounours-codeur
Posté le 07-10-2004 à 18:28:27  profilanswer
 

1) utilise efence
2) utilise valgrind
3) ça sent le double free ou la corruption massive :)

n°867289
darkoli
Le Petit Dinosaure Bleu
Posté le 07-10-2004 à 18:34:37  profilanswer
 

Taz a écrit :

1) utilise efence
2) utilise valgrind
3) ça sent le double free ou la corruption massive :)

Ah oui valgrind, je l'avais oublié celui-là ! Je ne pense pas que ce soit un double free. Qu'est que tu veux dire par "corruption massive" ?


Message édité par darkoli le 07-10-2004 à 18:34:53
n°867292
Taz
bisounours-codeur
Posté le 07-10-2004 à 18:36:11  profilanswer
 

bah si t'as un truc dans le décor mais là où il faudrait pas, tu peux te tapper des heap overflow ...

n°867311
darkoli
Le Petit Dinosaure Bleu
Posté le 07-10-2004 à 19:02:22  profilanswer
 

Voilà j'ai utilisé valgrind et j'obtiens ça :

==9734==  Address 0x1C531020 is 8 bytes before a block of size 1372012 alloc'd
==9734==    at 0x1B906EDD: malloc (vg_replace_malloc.c:131)
==9734==    by 0x8059D4B: nom_de_la_fonction1 (nom_du_programme.c:5727)

Et comme par hasard la zone mémoire que j'ai allouée fait la même taille. Qu'est ce que veut dire ce message ? C'est un warning ?


Message édité par darkoli le 07-10-2004 à 20:02:32
n°867313
Taz
bisounours-codeur
Posté le 07-10-2004 à 19:04:41  profilanswer
 

et sur cette exécution 0x1C531020 était la valeur de ea->lignes ?

n°867365
darkoli
Le Petit Dinosaure Bleu
Posté le 07-10-2004 à 20:04:50  profilanswer
 

Taz a écrit :

et sur cette exécution 0x1C531020 était la valeur de ea->lignes ?

D'après gdb, ce n'est pas la bonne valeur. C'est 0x40318008. Il va falloir que je refasse des tests demain (je ne suis plus au bureau). Au moment où valgrind affiche cet avertissement c'est la première fois que j'alloue la variable et à ce moment là (juste avant) elle est positionné à NULL.


Message édité par darkoli le 07-10-2004 à 20:08:48
n°867377
Taz
bisounours-codeur
Posté le 07-10-2004 à 20:15:44  profilanswer
 

tu peux utiliser les techniques d'empoisonnement pour vérifier que tout est bien initialiser. plutot que de mettre NULL, tu peux y foutre 0xdeadbeef :)

n°868543
el muchach​o
Comfortably Numb
Posté le 08-10-2004 à 21:19:48  profilanswer
 

darkoli a écrit :

Voilà j'ai utilisé valgrind et j'obtiens ça :

==9734==  Address 0x1C531020 is 8 bytes before a block of size 1372012 alloc'd
==9734==    at 0x1B906EDD: malloc (vg_replace_malloc.c:131)
==9734==    by 0x8059D4B: nom_de_la_fonction1 (nom_du_programme.c:5727)

Et comme par hasard la zone mémoire que j'ai allouée fait la même taille. Qu'est ce que veut dire ce message ? C'est un warning ?


 
Euh, tu ne veux pas donner la sortie intégrale de Valgrind ? Parce que là, j'ai l'impression que tu as tronqué le message, ce qui ne va pas nous aider.
 
Taz> Ce 0xdeadbeef me rappelle vaguement qq chose, mais je ne me souviens plus trop quoi. Tu peux rappeler cette technique ?


Message édité par el muchacho le 08-10-2004 à 21:23:39
n°868790
Joel F
Real men use unique_ptr
Posté le 09-10-2004 à 00:38:01  profilanswer
 

deadbeef ==> Dead Beef (viande morte) en english, c est un pattern de byte
moins aleatoire que NULL qui te permet de voire ds les debug le spointeurs qui foirent.
 
0xbada110c est pas mal aussi ^^

mood
Publicité
Posté le 09-10-2004 à 00:38:01  profilanswer
 

n°872340
darkoli
Le Petit Dinosaure Bleu
Posté le 13-10-2004 à 13:55:29  profilanswer
 

J'ai trouvé (la trace de valgrind était plus claire cette fois-ci) !!!
En fait c'est tout con et c'est tout simplement dû à un copier/coller non modifié.
 
Dans un cas je dois réaliser un calcul sur une seule ligne du tableau et dans un autre sur toutes les lignes. Donc j'avais une variable qui me donnais le numéro de ligne à traiter ou -1 pour indiquer qu'il fallait faire toutes les lignes.
 
Et dans la partie où je devais modifier toutes les lignes, j'avais laisser traîner ma variable qui valait alors -1. Donc le programme devait mettre à jour la case -1 du tableau.
 
Si ce n'est pas clair, voilà un exemple (chercher l'erreur) :

if (index >= 0)
 {
  /* Quelques lignes de code ... */
  faire(tab[index].lapin, &tab[index].lapin);
 }
else
 {
  for (i=0;i<taille_tableau;i++)
   {
    /* Quelques lignes de code ... */
    faire(tab[index].lapin, &tab[index].lapin);
   }
 }


Avec un PC sous Linux ça "passe" en revanche avec une station Sun sous Unix, ça ne passe pas : "Bus Error(coredump)".


Message édité par darkoli le 13-10-2004 à 13:58:22

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
n°872389
Taz
bisounours-codeur
Posté le 13-10-2004 à 14:19:02  profilanswer
 

t'es sur que t'as pas des merdes d'alignement ? sous Linux, fais tourner dans valgrind

n°872418
darkoli
Le Petit Dinosaure Bleu
Posté le 13-10-2004 à 14:54:32  profilanswer
 

Taz a écrit :

t'es sur que t'as pas des merdes d'alignement ? sous Linux, fais tourner dans valgrind

La seule erreur que m'a signalée valgrind en dehors de ce problème, c'est qu'une variable n'est pas initialisée alors qu'elle est utilisée pour un test. Mais cette variable est initialisée dans une fonction juste avant le test mais valgrind ne le "voit" pas.


Message édité par darkoli le 13-10-2004 à 14:55:30

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
n°872535
Taz
bisounours-codeur
Posté le 13-10-2004 à 17:12:29  profilanswer
 

ça coredump à quel endroit sur sparc ?

n°874427
el muchach​o
Comfortably Numb
Posté le 15-10-2004 à 21:00:35  profilanswer
 

darkoli a écrit :

J'ai trouvé (la trace de valgrind était plus claire cette fois-ci) !!!
En fait c'est tout con et c'est tout simplement dû à un copier/coller non modifié.
 
Dans un cas je dois réaliser un calcul sur une seule ligne du tableau et dans un autre sur toutes les lignes. Donc j'avais une variable qui me donnais le numéro de ligne à traiter ou -1 pour indiquer qu'il fallait faire toutes les lignes.
 
Et dans la partie où je devais modifier toutes les lignes, j'avais laisser traîner ma variable qui valait alors -1. Donc le programme devait mettre à jour la case -1 du tableau.
 
Si ce n'est pas clair, voilà un exemple (chercher l'erreur) :

if (index >= 0)
 {
  /* Quelques lignes de code ... */
  faire(tab[index].lapin, &tab[index].lapin);
 }
else
 {
  for (i=0;i<taille_tableau;i++)
   {
    /* Quelques lignes de code ... */
    faire(tab[index].lapin, &tab[index].lapin);
   }
 }


Avec un PC sous Linux ça "passe" en revanche avec une station Sun sous Unix, ça ne passe pas : "Bus Error(coredump)".


 
Je pige pas pourquoi tu as besoin de passer deux fois tab[index].lapin à ta fonction, une fois par valeur, l'autre par référence. Je ne sais pas ce qu'elle fait, mais ça me parait un peu bizarre. Par pur réflexe, j'éviterais cela. A mon avis, tel quel, il y a des chances pour que le comportement soit indéfini.
Que se passe-t'il si tu passes par une variable intermédiaire ?, du genre :
faire(tab[index].lapin, &temp);  
tab[index].lapin = temp;

n°874428
Taz
bisounours-codeur
Posté le 15-10-2004 à 21:02:30  profilanswer
 

[Résolu] ?

n°874437
el muchach​o
Comfortably Numb
Posté le 15-10-2004 à 21:10:53  profilanswer
 

Je sais pas, j'ai rien compris. Je crois que darkoli essaye de nous dire qe dans son code, on peut tomber dans un branchement où index < 0, et donc tab[index] explose, il aurait du y avoir tab[i] à la place, ou un truc comme ça. Ceci dit, son code, je le sens pas.


Message édité par el muchacho le 15-10-2004 à 21:13:44
n°874475
darkoli
Le Petit Dinosaure Bleu
Posté le 15-10-2004 à 21:54:57  profilanswer
 

el muchacho a écrit :

Je sais pas, j'ai rien compris. Je crois que darkoli essaye de nous dire qe dans son code, on peut tomber dans un branchement où index < 0, et donc tab[index] explose, il aurait du y avoir tab[i] à la place, ou un truc comme ça. Ceci dit, son code, je le sens pas.


Oui c'est ça. En fait dans un cas je dois réaliser un traitement pour toutes les lignes d'un tableau mais de temps en temps je dois appliquer ce même traitement à une seule des lignes du même tableau.
 
Pour savoir ce que je dois faire j'utilise une variable qui me donne le numéro de la ligne (entre 0 et taille-1). Si cette variable vaut -1 je dois traiter toutes les lignes.
 
Mais je me suis inspiré du code que j'utilisais pour le traitement d'une seule ligne pour réaliser le traitement de l'ensemble des lignes. Et comme un boulet j'ai laissé cette variable (qui valait -1) au lieu d'utiliser le compteur.
 
Oui c'est résolu !


Message édité par darkoli le 15-10-2004 à 21:59:38

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html
n°874482
darkoli
Le Petit Dinosaure Bleu
Posté le 15-10-2004 à 21:58:16  profilanswer
 

el muchacho a écrit :

Je pige pas pourquoi tu as besoin de passer deux fois tab[index].lapin à ta fonction, une fois par valeur, l'autre par référence. Je ne sais pas ce qu'elle fait, mais ça me parait un peu bizarre. Par pur réflexe, j'éviterais cela. A mon avis, tel quel, il y a des chances pour que le comportement soit indéfini.
Que se passe-t'il si tu passes par une variable intermédiaire ?, du genre :
faire(tab[index].lapin, &temp);  
tab[index].lapin = temp;

Oui c'est vrai mais c'est une fonction présente dans une des bibliothèques qu'on utilise au boulot et c'est assez compliqué d'aller la modifier. Cette fonction a toujours bien fonctionné même si la façon dont on l'utilise n'est pas très propre !!! (Je vais vérifier lundi !!!)


Message édité par darkoli le 15-10-2004 à 21:59:26

---------------
Le site de l'année :D (XHTML 1.0 strict) : http://darkoli.free.fr/index.html

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  free(): invalid pointer 0x40318008! [Résolu]

 

Sujets relatifs
Sendmail ne focntionne pas sur Free???session php chez free
[RESOLU] mysql_numrows(): is not a valid MYSQL result ... /sessions[C] Possible de faire un extern sur une union de struct [RESOLU] ?
[HTML/PHP][Résolu] Problème de sauvegarde pour les formulairesEst ce normal que la fonction rmdir() ne marche pas chez free ?
[RESOLU]probleme avec ma sessionSupprimer tout ce qui n'est pas lettre et chiffre (resolu)
[RESOLU] problème de condition sur un requête SQLProbleme d'une simple expression reguliere [RESOLU]
Plus de sujets relatifs à : free(): invalid pointer 0x40318008! [Résolu]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR