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 :

Fuite memoire getpwuid


Sujet :

C

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut Fuite memoire getpwuid
    Bonjour,

    J'ai un petit problème que voici (UNIX) :

    Je désire récupérer le chemin du dossier Home de l'utilisateur qui lance mon programme, pour ce j'utilise la fonction getpwuid, qui prend un uid_t en paramètre et retourne un pointeur sur struct passwd.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int             init_inf(t_data *d)
    {
      struct passwd *p;
     
      d->uid = getuid();
      if ((p = getpwuid(d->uid)) != NULL)
        {
          if ((d->u_name = strdup(p->pw_name)) == NULL)
             return (FAILURE_E);
          if ((d->u_home = strdup(p->pw_dir)) == NULL)
             return (FAILURE_E);
          free(p->pw_name);
          return (SUCCESS_E);
        }
      show_error(2, PRGM ": " ENOINFO "\n");
      return (FAILURE_E);
    }
    Voici la fonction.
    Il se trouve que j'ai quelques fuites de memoire :

    in use at exit: 2301 bytes in 9 blocks.
    J'ai essayé de free tous les pointeurs de la structure, il se trouve que seul pw_name ne me sort pas de warning.

    (Les fuites ne proviennent pas des strdup)

    Voici la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     struct passwd {
                       char    *pw_name;       /* user name */
                       char    *pw_passwd;     /* encrypted password */
                       uid_t   pw_uid;         /* user uid */
                       gid_t   pw_gid;         /* user gid */
                       time_t  pw_change;      /* password change time */
                       char    *pw_class;      /* user access class */
                       char    *pw_gecos;      /* Honeywell login info */
                       char    *pw_dir;        /* home directory */
                       char    *pw_shell;      /* default shell */
                       time_t  pw_expire;      /* account expiration */
                       int     pw_fields;      /* internal: fields filled in */
               };
    J'ai essayé avec getpwuid_r, mêmes fuites.

    Voila, si quelqu'un connait une solution à ceci, c'est avec plaisir que je l'accepte.

    Cdlt.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Tusbar Voir le message
    Bonjour,

    J'ai un petit problème que voici (UNIX) :

    Je désire récupérer la le chemin du dossier Home de l'utilisateur qui lance mon programme, pour ce j'utilise la fonction getpwuid, qui prend un uid_t en paramètre et retourne un pointeur sur struct passwd.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int             init_inf(t_data *d)
    {
      struct passwd *p;
     
      d->uid = getuid();
      if ((p = getpwuid(d->uid)) != NULL)
        {
          if ((d->u_name = strdup(p->pw_name)) == NULL)
             return (FAILURE_E);
          if ((d->u_home = strdup(p->pw_dir)) == NULL)
             return (FAILURE_E);
          free(p->pw_name);
          return (SUCCESS_E);
        }
      show_error(2, PRGM ": " ENOINFO "\n");
      return (FAILURE_E);
    }
    Voici la fonction.
    Il se trouve que j'ai quelques fuites de memoire :

    J'ai essayé de free tous les pointeurs de la structure, il se trouve que seul pw_name ne me sort pas de warning.

    (Les fuites ne proviennent pas des strdup)
    Hé si car d->u_name a été alloué par strdup() !!!
    Donc faut que tu fasses un free(d->u_name) (et accessoirement aussi un free(d->u_home)) et non de p->pw_name (ni d'aucun autre membre de p car il n'y a pas eu d'allocation pour eux)...

    Citation Envoyé par Tusbar Voir le message
    Je désire récupérer la le chemin du dossier Home de l'utilisateur qui lance mon programme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char *home;
    home=strdup(getenv("HOME"));
    printf("%s\n", home);
    free(home);
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Hé si car d->u_name a été alloué par strdup() !!!
    Donc faut que tu fasses un free(d->u_name) (et accessoirement aussi un free(d->u_home)) et non de p->pw_name (ni d'aucun autre membre de p car il n'y a pas eu d'allocation pour eux)...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char *home;
    home=strdup(getenv("HOME"));
    printf("%s\n", home);
    free(home);

    "(Les fuites ne proviennent pas des strdup)"

    Cela signifie que je les free plus tard dans mon programme, comme un millier d'autre peut être. Sans l'appel a getpwuid je n'ai aucune fuite dans mon programme.

    Sinon, je n'ai pas demande de solution alternative, mais bien une aide par rapport a cette fonction. Si je n'utilise pas getenv, c'est qu'il ya une raison.

    Cdlt.



    EDIT :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #include <pwd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
     
    int             main(void)
    {
      struct passwd *p;
      char          *u_name;
      char          *u_home;
     
      if ((p = getpwuid(getuid())) != NULL)
        {
          u_name = strdup(p->pw_name);
          u_home = strdup(p->pw_dir);
     
          /* free(p->pw_name); */
     
          free(u_name);
          free(u_home);
          return (0);
        }
      return (1);
    }
    Valgrind :
    ==4351== malloc/free: in use at exit: 3325 bytes in 10 blocks.
    ==4351== malloc/free: 36 allocs, 26 frees, 37310 bytes allocated.
    Sans les commentaires sur p->pw_name :
    ==4387== malloc/free: in use at exit: 2301 bytes in 9 blocks.
    ==4387== malloc/free: 36 allocs, 27 frees, 37310 bytes allocated.
    Les memes fuites que plus haut...

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Que se passe-t-il si tu utilises getpwuid_r() à la place ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Exactement la meme chose, sauf que p->pw_name est deja free, en effet je lui passe l'adresse d'une structure en dur.

    Cdlt.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Tusbar Voir le message
    Sinon, je n'ai pas demande de solution alternative, mais bien une aide par rapport a cette fonction. Si je n'utilise pas getenv, c'est qu'il ya une raison.
    Alors ne commence pas ton post par
    je désire récupérer le HOME
    mais plutôt par
    j'ai un problème sur getpwuid
    Citation Envoyé par Tusbar Voir le message
    "(Les fuites ne proviennent pas des strdup)"

    Cela signifie que je les free plus tard dans mon programme, comme un millier d'autre peut être. Sans l'appel a getpwuid je n'ai aucune fuite dans mon programme.
    Alors faut tester avec un programme tout simple de ce style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int main()
    {
      struct passwd *p;
      // p=getpwuid(getuid());
      show_error(2, PRGM ": " ENOINFO "\n");
    }
    Regarder si t'as une fuite mémoire, puis décommenter la 2° ligne et regarder de nouveau si t'as toujours ta fuite. Je l'aurais bien fait mais mon compilo Code::Block ne connait pas la fonction "show_error()"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Je me demande ou j'ai parle de récupérer une variable d'environnement.

    (cf. le titre du thread)

    Sve@r, regarde trois posts plus haut.

    Les fuites de mémoire, merci je sais ce que je code, proviennent de getpwuid. Pas de show_error()... c'est un simple write(2) sur stderr.

    La question n'est pas : "D'où proviennent mes fuites de mémoire ?"

    Mais "Comment puis-je libérer la mémoire utilisée par getpwuid ?"

    Merci, cordialement;

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Tusbar Voir le message
    La question n'est pas : "D'où proviennent mes fuites de mémoire ?"

    Mais "Comment puis-je libérer la mémoire utilisée par getpwuid ?"
    tu as changé de question :

    J'ai un petit problème que voici (UNIX) :

    Je désire récupérer le chemin du dossier Home de l'utilisateur qui lance mon programme


    Sve@r t'as donné la solution que n'importe quel programmeur de C ferait..

    Si maintenant tu tiens absolument à utiliser getpwuid, n'insulte pas les autres en disant qu'ils n'ont rien compris...

    Il y a peut-être un problème avec cette fonction, mais la manière normale d'obtenir le chemin complet du home d'un utilsateur est celle de Sve@r...(et en plus tu n'as même pas besoin d'utiliser strdup)...


    NOTE : il y a 6 char * dans la structure, et tu n'en libères qu'un seul, le nom....

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Sinon faut lire les posts en entier ?

    Je n'ai insulte personne.

    Sve@r t'as donné la solution que n'importe quel programmeur de C ferait..
    En effet, or il se trouve que quand j'exécute mon programme, l'environnement n'est pas encore défini.


    NOTE : il y a 6 char * dans la structure, et tu n'en libères qu'un seul, le nom....
    J'ai essayé de free tous les pointeurs de la structure, il se trouve que seul pw_name ne me sort pas de warning.

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Tusbar Voir le message
    En effet, or il se trouve que quand j'exécute mon programme, l'environnement n'est pas encore défini.
    euh......


    Si tu as un utilsateur défini, tu as un environnement, non ??????????

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Pas si loin que ça...

    J'ai un utilisateur défini, donc je crée l'environnement.

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 115
    Par défaut
    Bon j'ai demande autour de moi...

    Les fuites proviennent de la libc (pointeurs perdus).

    Et bien on va se recoder un parser du fichier passwd hein.

    Visiblement coder sans fuite de mémoire importe peu...

    "Ce ne sont que 2301 bytes, t'as 2Go de RAM !!!" diront certains.

    Merci pour vos réponses.

Discussions similaires

  1. Réponses: 4
    Dernier message: 31/10/2008, 08h31
  2. fuite memoire avec sfml
    Par themulot dans le forum SFML
    Réponses: 2
    Dernier message: 27/11/2007, 10h25
  3. [2.0] Comment tracer les fuites mémoire ?
    Par StormimOn dans le forum C++/CLI
    Réponses: 9
    Dernier message: 02/11/2007, 07h22
  4. [java] fuite memoire quand 2 process!
    Par vince3320 dans le forum Langage
    Réponses: 6
    Dernier message: 01/03/2007, 16h50
  5. [VC++6] probleme fuite memoire CLIST ?
    Par athilla dans le forum MFC
    Réponses: 16
    Dernier message: 22/11/2005, 16h01

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