IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Comportement étrange avec free.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut Comportement étrange avec free.
    Bonjour,

    Je poste car j'ai un soucis de free.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    mydebug("prec->fields[i].data.value.a_string=[%s]\n", prec->fields[i].data.value.a_string);
    mydebug("strlen=[%d]\n", strlen(prec->fields[i].data.value.a_string));
    free(prec->fields[i].data.value.a_string);
    mydebug("fin\n");

    mydebug est une fonction qui log avec un flush.
    Le debug affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    prec->fields[i].data.value.a_string=[31313200   ]
    strlen=[11]
    Mais pas "fin", et pour cause, il y a eu un seg fault...
    Mais dans la mesure ou on peut afficher le contenu de la variable et calculer sa taille avec un strlen, le fait qu'il ne puisse pas faire de free me semble completement inconpréhensible. Bref, si quelqu'un a la moindre piste, je suis prenneur !

    A noter que ce code se trouve dans une boucle ou i est incrémenté de 1 à 140, et je n'ai le problème que pour un seul cas (le 119)...

    Merci d'avance ;-)

  2. #2
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    pour commencer comme trace je proposerai ca histoire d etre bien sur d ou on en est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    mydebug("prec->fields[%d].data.value.a_string=[%s]\n", i, prec->fields[i].data.value.a_string);
    mydebug("strlen=[%d]\n", strlen(prec->fields[i].data.value.a_string));
    free(prec->fields[i].data.value.a_string);
    mydebug("fin\n");
    mais pourrais tu nous montrer comment est allouée et remplie cette structure.

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Rakken Voir le message
    Bonjour,



    Mais dans la mesure ou on peut afficher le contenu de la variable et calculer sa taille avec un strlen, le fait qu'il ne puisse pas faire de free me semble completement inconpréhensible. Bref, si quelqu'un a la moindre piste, je suis prenneur !

    A noter que ce code se trouve dans une boucle ou i est incrémenté de 1 à 140, et je n'ai le problème que pour un seul cas (le 119)...

    Merci d'avance ;-)
    si strlen ne se plante pas celà signifie simplement que le pointeur qui lui est donné en argument correspond bien à une adresse mémoire du processus et qu'il trouve un byte '\0' avant de tomber sur une adresse mémoire non mappée…

    si free se plante avec la même adresse mémoire cela peut signifier :
    que cette adresse n'a pas été allouée par l'allocateur …
    que les données du bloc mémoire utilisée par l'allocateur ont été corrompues par le programme… en général quelque chose du genre un strcpy, memmove, … qui déborde…

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Par défaut
    Hello,
    en voyant le code que tu nous montres, il ne semble pas y avoir d'erreur. Du coup si tu es sous unix je te conseil d'utiliser des outils pour verifier tes acces memoire tel que valgrind, ca te permettra deja de voir si tu fais des lectures/ecritures qui debordes sans que tu le vois.

    Sinon montre nous comment tu alloues ta structure. Une derniere chose, si tu deplace le pointeur de la string, le remet tu bien en place avant de free ? (typiquement un truc du genre : (prec->fields[i].data.value.a_string)++ )

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    strlen va juste te dire à quelle distance se trouve le premier '\0' depuis le pointeur que tu lui donnes. Il ne plante pas tant que l'adresse fournie est valide même si elle n'a pas été allouée par malloc! free plante: plusieurs pistes possibles:
    1. Comme le dit oniric, ton pointeur d'adresse s'est déplacé entre temps,
    2. la chaîne a été alloué avec une taille ne tenant pas compte du '\0'
    3. la chaîne a encore plus brutalement débordée,
    4. l'écrasement mémoire peut avoir eu lieu juste avant le bloc mémoire de la chaîne,
    5. le pointeur n'est pas un bloc alloué dynamiquement mais un tableau de taille fixe,
    6. la chaîne a déjà été libérée.

    Et il y en a surement d'autre encore.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Si tu travailles sous Visual C++, tu peux installer purify (payant je crois...). Il va tester toute ta mémoire. Ce module m'a rendu bien des services !

  7. #7
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    Merci pour toutes ces réponses. Je pensais que faire un printf d'un emplacement mémoire non alloué plantait systématiquement. D'où ma surprise initiale, mais maintenant que vous le dites, c'est vrai que le C étant ce qu'il est, on peut lire un peu n'importe où dans la mémoire.
    Bref, j'ai fini par trouver une solution... ca me semble étrange, mais depuis, je n'ai pas réussi à reproduire le seg fault.
    En fait, après ce free qui plante, un élément de la structure globale (qui venais donc de se faire désallouer) était encore lu une derniere fois. Ce qui me provoquait des incohérences dans certaines valeurs (c'est comme ça que je m'en suis rendu compte). J'ai donc déplacé la fonction de libération de mémoire après ma dernière lecture, et depuis, plus de seg fault.
    Au final, je n'ai toujours pas compris pourquoi avant ça plantait, mais ça m'a permis de trouver d'autres soucis et en résolvant ces autres soucis, désormais, tout fonctionne.
    J'ai réussi à réunir théorie et pratique, ca marche, et je ne sais pas pourquoi Mais résolut tout de même ;-)

    Et je vais aller jeter un oeil du coté des outils que vous m'avez proposé, ca à l'air plutôt interessant.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AJAX] Comportement étrange avec ajax
    Par devphpdid dans le forum AJAX
    Réponses: 2
    Dernier message: 20/04/2015, 10h54
  2. Réponses: 0
    Dernier message: 02/07/2013, 11h53
  3. Réponses: 41
    Dernier message: 25/03/2013, 11h39
  4. Comportement étrange avec "order by"
    Par Warluck dans le forum SQL
    Réponses: 2
    Dernier message: 04/11/2010, 21h06
  5. Comportement étrange avec les index et "order by"
    Par Dia_FR dans le forum Requêtes
    Réponses: 5
    Dernier message: 18/08/2008, 09h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo