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 :

Retour aux sources, la liberation de memoire


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 77
    Par défaut Retour aux sources, la liberation de memoire
    Bonjour,

    Depuis que j'ai commence la programmation, quand je veux remplir une chaine dans une autre fonction j'envoie le type fonction_de_remplissage(str), et pour liberer ou allouer de la memoire, j'envoie create_or_free(&str).

    Je pense ne pas me tromper pour l'allocation de memoire, mais je commence a voir de serieux doutes pour le free, vu que malloc renvoir un pointeur sur adresse, je devrais pouvoir envoyer le pointeur directement, non ? Free ne retournant pas de valeur, et quand on le re print, meme en ayant free on a encore les donnees, j'aimerais que quelqu'un confirme mes doutes afin d'eviter toute perte de memoire a l'avenir.

    J'aimerais faire de la facon suivante, car actuellement je fais que des void(&str) pour creer et liberer mes chaines (en recuperant des char *(*str), et autres types, et je voudrais profiter des return en restant dans le 0 perte de memoire.

    Merci !

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    char *create(char *str)
    {
    int len;
     
    len = 4;
    str = malloc(len + 1 * sizeof(*str));
    return (str);
    }
     
    void  full(char *s1, char *s2)
    {
    strcpy(s1, s2);
    }
     
    void lib(char *str)
    {
    free(str);
    }
     
    int main()
    {
    char *str = NULL;
     
    str = lib(full(create(str), "toto"));
    return(0);
    }
     
    /* AU LIEU DE CA, VOILA CE QUE JE FAIS, J'AI JAMAIS EUT DE PROBLEME, MAIS JE TROUVE CA SUPER SALE ! */
     
    void create(char *(*str))
    {
    int len = 4;
    str = malloc(len + 1 * sizeof(*(*str)));
    }
     
    void  full(char *s1, char *s2)
    {
    strcpy(s1, s2
    }
     
    void lib(char *(*str))
    {
    free(*str);
    }
     
    int main()
    {
    char *str = NULL;
     
    create(&str);
    full(str, "toto");
    lib(&str);
    return(0);
    }

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 145
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    J'ai eu un peu de mal à comprendre la question. Mais comme première idée qui m'est venu à la tête, c'est que si vous avez des doutes sur les fuites de mémoire ( et autre débordement ), et que vous êtes sous Linux, utilisez valgrind.
    ( c'est une petite merveille cet outil )

    Maintenant, revenons au code.
    Les deux codes sont juste ( sinon, j'ai un peu mal vu ).
    Dans le premier, je trouve la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    str = lib(full(create(str), "toto"));
    Assez barbare. En fait, elle est fausse. Pourquoi? Le compilateur devrait le dire d'ailleurs .
    Simplement car lib() prend un pointeur sur un char* ( c'est partie d'une bonne intention ) mais que full(), ne retourne pas de pointeur sur un char* ( ce qui est normale ). Du coup, lib attrappe une valeur indeterminée comme paramètre, et va faire une libération de quelque chose d'indéterminée. Ici il y aura des erreur de segmentation, ou autre.
    Et puis même chose, pour str, car lib() return un void soit rien, soit str aura une valeur indéterminé.

    Maintenant, le deuxième code, à une chose inutile.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void lib(char *(*str))
    {
    free(*str);
    }
    Dans ce cas là, il faut mieux faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void lib(char *str)
    {
    free(str);
    }
    ou alors plus sécuritaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void lib(char *(*str))
    {
    free(*str);
    *str = NULL;
    }
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 77
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    str = lib(full(create(str), "toto"));
    Assez barbare. En fait, elle est fausse. Pourquoi? Le compilateur devrait le dire d'ailleurs .
    Simplement car lib() prend un pointeur sur un char* ( c'est partie d'une bonne intention ) mais que full(), ne retourne pas de pointeur sur un char*
    Exact, je me suis concentre sur la liberation de memoire, c'est un oublie de ma part, je comptais en effet retourner un char *.

    Citation Envoyé par LittleWhite Voir le message
    Maintenant, le deuxième code, à une chose inutile.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void lib(char *(*str))
    {
    free(*str);
    }
    Dans ce cas là, il faut mieux faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void lib(char *str)
    {
    free(str);
    }
    Voila qui répond a mes doutes ! Merci beaucoup.

    Citation Envoyé par LittleWhite Voir le message
    ou alors plus sécuritaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void lib(char *(*str))
    {
    free(*str);
    *str = NULL;
    }
    Es ce vraiment plus sécuritaire ? Ou tu veux dire, par rapport a mon code peut etre ? C'est en gros ma façon de faire, mais je trouve ca assez sale...

    Merci encore, bonne journee !

  4. #4
    Membre émérite
    Avatar de Pouet_forever
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 671
    Par défaut
    Disons que c'est plus propre de mettre à NULL un pointeur qui a été 'free'. Au moins tu sais qu'il est 'vide'.

    Après je ne suis pas sûr que cette écriture soit correcte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void lib(char *str)
    {
    free(str);
    }
    Après, peut-être que je me trompe.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 77
    Par défaut
    C'est la question que je me pose, car faire:

    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
    char *full_str(char *str)
    {
    str = malloc(2 *sizeof(*str));
    str[0] = 'O';
    str[1] = '\n';
    return (str);
    }
     
    int main()
    {
    char *str = NULL;
     
    str = full_str(str);
    free(str);
    }
    full_str renvoie un pointeur sur adresse si j'ai bien compris, donc dans le main on fait pointer un pointeur, sur un pointeur sur adresse, ce qui me semble etre source d'ennuis pour free notamment...

    Ou y a t'il une difference que de faire:

    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
    char *full_str()
    {
    char *s2 = NULL;
     
    s2 = malloc(2 * sizeof(*s2));
    s2[0] = 'O';
    s2[1] = '\n';
    return (s2);
    }
     
    int main()
    {
    char *str = NULL;
     
    str = full_str();
    free(str);
    }

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Les deux codes sont faux et pour la même raison. Prenons le premier en exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    str = malloc(sizeof(*str));
    str est un char * donc *str est un char. Alors, sizeof(*str) est la même chose que sizeof(char) qui vaut toujours 1.
    Cette ligne est donc équivalente à
    Cette allocation est bien sûr insuffisante pour stocker tes caractères.

  7. #7
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Pouet_forever Voir le message
    Après je ne suis pas sûr que cette écriture soit correcte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void lib(char *str)
    {
    free(str);
    }
    Ah et pourquoi ?

    Citation Envoyé par student_ Voir le message
    full_str renvoie un pointeur sur adresse si j'ai bien compris, donc dans le main on fait pointer un pointeur, sur un pointeur sur adresse, ce qui me semble etre source d'ennuis pour free notamment...
    Qu'entends-tu par pointeur sur adresse ?

    Sinon, aussi bien str dans main que le retour de full_str() sont des pointeur sur char.
    • str vaut NULL avant l'appel de full_str() puis contient l'adresse retourné par malloc() après le retour de full_str() (ou NULL en cas d'erreur).
    • Le retour de full_str est l'adresse retourné par malloc() (ou NULL en cas d'erreur).


    Mais il n'y a pas de problème ici (enfin mis à part la remarque de diogene et l'absence de vérification de la valeur de retour de malloc()). Et en particulier rien qui ne pose problème lors de l'appel à free().

    Fonctionnellement, les deux codes sont équivalent.

    Au passage,
    • Si full_str() est censé, comme son nom l'indique, créer une chaîne de caractère, il faut réservé un char de plus et y mettre le \0 terminal.
    • Le second code pourrais s'écrire plus simplement :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char *full_str()
    {
       char *s2 = malloc(2 * sizeof(*s2));
       s2[0] = 'O';
       s2[1] = '\n';
       return (s2);
    }
     
    int main()
    {
       char *str = full_str();
       free(str);
    }

Discussions similaires

  1. [olivier.taranis] retour aux sources
    Par olivier.taranis dans le forum Présentations
    Réponses: 3
    Dernier message: 23/04/2014, 09h12
  2. Retour aux sources
    Par F@bien.fd dans le forum Débuter
    Réponses: 10
    Dernier message: 23/09/2011, 11h59
  3. [Débat] MVC : le retour aux sources ?
    Par CUCARACHA dans le forum ASP.NET
    Réponses: 19
    Dernier message: 11/06/2009, 09h34
  4. liberation de memoire d une fenetre modale
    Par ienien dans le forum MFC
    Réponses: 6
    Dernier message: 04/01/2006, 13h53
  5. Réponses: 6
    Dernier message: 24/10/2005, 19h12

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