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 :

Comment vérifier si un pointeur pointe vers une zone allouée?


Sujet :

C

  1. #1
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut Comment vérifier si un pointeur pointe vers une zone allouée?
    Bonjour à tous.


    On m'a refilé un programme écrit par un collègue il y a plusieurs années. A la base il a été écrit sous AIX, donc j'étais censé simplement le recompiler et le faire marcher sous Debian. Mais j'ai des erreurs en pagailles, apparemment le programme est archi buggé, je n'arrive pas à comprendre qu'il ait pu marcher plusieurs années. De plus le code est écrit sous la forme de deux fichiers de 800 lignes chacun, avec des fonctions qui font 4 pages, et quasiment aucun commentaire, la grosse galère, quoi.


    N'ayant pas d'autre choix, je me suis plongé dans l'analyse de ce programme, et j'ai commencé à traquer les erreurs de segmentation. Il apparait que ces erreurs interviennent systématiquement pendant ou immédiatement après l'appel de la fonction chargée de libérer la mémoire allouée. Et je rencontre notamment des erreurs liées à des double-free(), dont je ne comprend pas trop d'où ils sortent. D'où ma question :


    Est-il possible de vérifier si un pointeur pointe vers une zone allouée?


    parce que je mettrais bien en place un test du type
    si (mémoire déjà libérée)
    ne rien faire
    sinon
    libérer la mémoire

    merci.

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

    en général il conseillé de mettre ton pointeur a NULL lorsque tu le desalloues, comme ca pas de probleme.
    free( NULL ); ca fait pas grand chose (rien meme et c'est garanti par la norme ) et pis c'est facile a tester.

    Sinon parfois un plantage sur le free c'est qu'il y a eu debordement de memoire.

  3. #3
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    si le programme est compilé avec l'option -g, tu peux utiliser valgrind.

  4. #4
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut
    @ BainE

    merci beaucoup, c'est ce que je fais toujours, mais l'ennui vient de la complexité du programme. Certaines instructions conditionnelles bougent les pointeurs, et parfois il manque un else, du coup il y a des variables mal initialisées qui sont parfois désalouées, ce genre de chose.. Et je n'ai pas encore relu tout le programme!


    @ nicolas.sitbon

    J'utilise gdb. Mais parfois il me retourne des choses pas exploitable (genre que l'erreur se serait produite dans la librairie libc6 de linux). C'est mieux valgrind?





    Sinon ce que j'aurais pensé faire, c'est faire un realloc : Je prend le pointeur, je le réalloue plus grand que ce qu'il n'a jamais pu être, et je le libère de suite, vous penser que ça pourrait faire quelque chose de propre?

  5. #5
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Aldian Voir le message
    @ nicolas.sitbon

    J'utilise gdb. Mais parfois il me retourne des choses pas exploitable (genre que l'erreur se serait produite dans la librairie libc6 de linux). C'est mieux valgrind?
    valgrind est tout indiqué dans ton cas!

  6. #6
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut
    Bon j'ai installé Valgrind.

    Mais comme je ne suis pas root, j'ai spécifié un répertoire d'installation différent, à savoir /home/aldian/valgrind. Le programme s'est installé, c'est génial


    Mais impossible de le lancer, très probablement parce que je n'ai pas exporté ce qu'il fallait dans le PATH. Et la question est : mais quoi?

    merci

  7. #7
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut
    Bon finalement ce n'était pas bien sorcier donc j'ai fini par trouver.

    Il suffisait d'éditer le fichier .bashrc et d'ajouter la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    export PATH=/home/aldian/valgrind/bin:$PATH
    Entre temps, j'ai fini par trouver un else manquant et à comprendre ses implications, ce qui m'a sorti de mon erreur introuvable, et gdb a trouvé les erreurs sans problème. J'ai tout de même lancé valgrind dessus et il me retourne un résultat des plus sympathiques (sauf erreur de ma part):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ==32344== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
    ==32344== malloc/free: in use at exit: 0 bytes in 0 blocks.
    ==32344== malloc/free: 1 allocs, 1 frees, 352 bytes allocated.
    ==32344== For counts of detected errors, rerun with: -v
    ==32344== All heap blocks were freed -- no leaks are possible.
    Mon problème est résolu, merci à vous.

    PS si quelqu'un a tout de même une réponse à :
    Sinon ce que j'aurais pensé faire, c'est faire un realloc : Je prend le pointeur, je le réalloue plus grand que ce qu'il n'a jamais pu être, et je le libère de suite, vous penser que ça pourrait faire quelque chose de propre?
    Ca m'intéresserait bien quand même (pour ma culture)

  8. #8
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Aldian Voir le message

    PS si quelqu'un a tout de même une réponse à :

    Ca m'intéresserait bien quand même (pour ma culture)
    J'avoue ne pas comprendre ce que tu veux faire...

  9. #9
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut
    Ben j'ai un pointeur qui pointe peut être (ou pas) sur une zone allouée.

    Donc si je fais un free dessus, j'ai une chance sur 2 d'avoir une erreur.
    Mais si je commence par faire un realloc il se passera ceci :

    Si la zone pointée par le pointeur était allouée, elle est juste redimensionnée.

    Si la zone n'était pas allouée, l'effet est le même que si on avait fait un malloc.

    Donc dans tout les cas lorsque l'on fait le free il a de la mémoire à libérer et il est content.


    ça marche ça?

  10. #10
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Ce que tu dis est faux, c'est le même principe pour realloc ou pour free :
    la plupart des systèmes écrivent des méta données dans une zone de 4 à 8 bytes juste avant la zone alloué. Quand tu fais un free ou un realloc, le système lit ces données pour savoir combien de byte ont été alloués. Soit la taille est bonne, soit le comportement chaotique.
    Il n'y a pas 36 manières de faire les choses bien, je recommande :
    - à la déclaration d'un pointeur, soit de le faire pointer vers une zone de mémoire valide, soit de le mettre explicitement à NULL
    - à la "libération" d'un pointeur de le remettre explicitement à NULL

    Rien ne t'empêche de te faire une macro pour t'aider :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FREE(ptr) free (ptr), (ptr) = NULL;

  11. #11
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Rien ne t'empêche de te faire une macro pour t'aider :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FREE(ptr) free (ptr), (ptr) = NULL;
    Personnellement, je préfère que ce soit explicite dans le code.

    Thierry

  12. #12
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    Personnellement, je préfère que ce soit explicite dans le code.

    Thierry
    Idem.

  13. #13
    Membre éprouvé

    Homme Profil pro
    Développeur J2EE Senior
    Inscrit en
    Mai 2008
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur J2EE Senior
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2008
    Messages : 419
    Points : 900
    Points
    900
    Par défaut
    Merci beaucoup de vos réponses. C'est également ce que je fais toujours. Mais dans le cas présent il s'agit d'un code très compliqué et développé par quelqu'un d'autre, et il y a des occasions dans lesquelles il fait des free sur des zones qui n'ont jamais été allouées. C'est la raisont pour laquelle je cherchais une solution alternative. Mais je vais devoir faire sans.

    Merci à vous

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/03/2010, 09h16
  2. Réponses: 4
    Dernier message: 23/12/2009, 13h26
  3. bouton qui pointe vers une page jsp
    Par redabadache3 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 29/10/2007, 15h33
  4. Réponses: 0
    Dernier message: 15/08/2007, 17h36
  5. Réponses: 11
    Dernier message: 24/07/2003, 10h24

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