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 :

question sur liberation de memoire


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 41
    Points
    41
    Par défaut question sur liberation de memoire
    Bonjour,

    Voila, j ai une la structure suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct u_info
    {
        int nb;
        char *data;
    } u_info_t;
    j ai une fonction qui creer un tableau de type u_info_t et qui doit le remplir.
    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
     
    u_info_t *fill_u_info(int len, char **name, int size)
    {
        int i;
        u_info_t *tab_info = (u_info_t *) calloc(len, sizeof(u_info_t));
        u_info_t *info_tmp;
        char **tmp = name
     
        if (tab_info != NULL)
        {
            for (i = 0; i < size; i++)
            {
                info_tmp = get_info(*tmp);
                if (info_tmp != NULL)
                {
                    tab_info[i].nb = info_tmp->nb;
                    tab_info[i].data = info_tmp->data;
                    free(info_tmp);
                    tmp++;
                }
                else
                {
                    // on desalloue tab_info;
                    // ....
                    tab_info = NULL;
                    break;
                }
            }
        }
     
        return tab_info;
    }
    Cela fonctionne, mais je voulais savoir si ceci etait correct ? surtout au niveau du free(info_tmp) car je desalloue seulement l espace de la structure, mais je ne desalloue pas l espace de de son champ data.


    Merci.


    MAJ :
    la fonction get_info() retourne une varaible de type u_info_t *.

  2. #2
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    a chaque malloc (ou calloc) correspond un free.

    c'est pas facile de repondre sans voir plus de code.

    basiquement, tu alloue quand t'as besoin, et tu libére quand t'as plus besoin en remettant tes pointeurs a NULL pour etre sur de planter en cas d'erreur dans le prog (histoire de voir le bug de suite)

    y manque:
    else
    {
    // on desalloue tab_info;
    // ....
    free(tab_info);
    tab_info = NULL;
    break;
    }

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    c pour cela que j ai mis un commentaire.
    Normalement ca aurait du etre quelque chose de ce genre (en pseudo langage)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    DEBUT:
    Tant que i < longueur de tab_info et que tab_info + i != NULL
        Si tab_info[i].data != NULL
            free(tab_info[i].data)
        i++
     
    free(tab_info)
    FIN
    Mais j ai eu la flemme de le mettre, car ma reellement ma fonction est beaucoup plus complique et que la je l ai simplifier vraiement un maximum, juste pour vous montrer mon incertitude.

    Mon incertitude vient du free(info_tmp) seulement.

  4. #4
    mat.M
    Invité(e)
    Par défaut
    Cela fonctionne, mais je voulais savoir si ceci etait correct ? surtout au niveau du free(info_tmp) car je desalloue seulement l espace de la structure, mais je ne desalloue pas l espace de de son champ data.
    D'après le code donné on fait des allocations avec calloc et après on teste si calloc a bien fonctionné .
    Il n'ya pas besoin de désallouer la ou tu as mis des commentaires pour la bonne raison que calloc n'aura pas fonctionné !

    u_info_t *tab_info = (u_info_t *) calloc(len, sizeof(u_info_t));
    u_info_t *info_tmp;
    char **tmp = name

    if (tab_info != NULL)
    Meeeff !
    Selon les compilos tab_info n'est pas initialisé forcément = à NULL !
    Avec VC++ par ex ,tab_info vaudra quelque chose comme 0xccccccc avant d'être affecté à une adresse par calloc
    Donc avant l'appel de calloc initialiser tab_info=NULL

  5. #5
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    si ta fonction get_info alloue dynamiquement un espace a l'adresse ou pointe le pointeur qu'elle retourne (je fait vraiment des phrases alacon ce soir), alors il y'as besoin d'un free. il n'y as pas plus de questions que ça a se poser y me semble.

    maintenant si c'est un probleme de conception, il semblerait que pour ce genre de chose il soit frequent que la fonction retourne un pointeur sur une variable statique de la fonction, ça permet d'eviter l'utilisation de malloc//free a repetition qui sont des operations couteuses.
    ça as le desavantage de rendre ta fonction non re-entrante.

    et puis sinon, on ne met pas de cast en C pour malloc//calloc.

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par mat.M
    Avec VC++ par ex ,tab_info vaudra quelque chose comme 0xccccccc avant d'être affecté à une adresse par calloc
    Donc avant l'appel de calloc initialiser tab_info=NULL
    Pourquoi ?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par mat.M
    Selon les compilos tab_info n'est pas initialisé forcément = à NULL !
    Avec VC++ par ex ,tab_info vaudra quelque chose comme 0xccccccc avant d'être affecté à une adresse par calloc
    Donc avant l'appel de calloc initialiser tab_info=NULL
    Quand je regarde le man voivi ce qui est dit :
    Pour calloc() et malloc(), la valeur renvoyée est un pointeur sur la mémoire allouée, qui est correctement alignée pour n'importe quel type de variable, ou NULL si la demande échoue.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ....
                if (info_tmp != NULL)
                {
                    tab_info[i].nb = info_tmp->nb;
                    tab_info[i].data = info_tmp->data;
                    free(info_tmp);
                    tmp++;
                }
    ....
    Alors ce n est pas la peine de mettre free(info_tmp) et que tout est correcte point de vu allocation memoire et tout ?

    le probleme est si j enleve free(info_tmp), alors lors du calloc de la prochaine iteration, on aura perdu l adresse memoire de info_tmp et on ne pourra plus y avoir acces.
    De plus, normalement free(info_tmp) ne desalloue pas la memoire du champs data !!!!

    Si j avais fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ....
                if (info_tmp != NULL)
                {
                    tab_info[i] = *info_tmp;
                    free(info_tmp);
                    tmp++;
                }
    ....
    je pense que le free(info_tmp) n aurat pas ete util ... Enfin je crois .
    ERF si quelqun pourrait confirmer mes dires (ou refuter mes conneries).

  9. #9
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    Citation Envoyé par nivose110
    Alors ce n est pas la peine de mettre free(info_tmp) et que tout est correcte point de vu allocation memoire et tout ?
    je ne sais pas comment marche ta fonction, si elle utilise l'allocation dynamique, il faut free.
    quand ... c'est a toi de voir.
    personellement je trouve bete d'allouer dynamiquement dans ta fonction get_info a chaque iteration de ta boucle for.

    De plus, normalement free(info_tmp) ne desalloue pas la memoire du champs data !!!!
    exact. mais d'apres ton code ce n'est pas un probleme, c'est meme devenu une "feature"

  10. #10
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par nivose110
    De plus, normalement free(info_tmp) ne desalloue pas la memoire du champs data !!!!
    Exact. Et à un moment ou à un autre il faudra bien la libérer cette mémoire.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 41
    Points
    41
    Par défaut
    Donc se qui serait mieux serait de faire ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void get_info(u_info_t *info, char *tmp);
    Cette fonction va remplir le pointeur info.

    et dans u_info_t *fill_u_info je met



    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
     
    u_info_t *fill_u_info(int len, char **name, int size)
    {
        int i;
        u_info_t *tab_info = (u_info_t *) calloc(len, sizeof(u_info_t));
        u_info_t *info_tmp;
        char **tmp = name
     
        if (tab_info != NULL)
        {
            for (i = 0; i < size; i++)
            {
               info_tmp = tab_info + i;
               get_info(info_tmp, *tmp);
     
                // si get_info foire il met info_tmp a NULL.
                if (info_tmp == NULL)
                {
                    // on desalloue tab_info;
                    // ....
                    tab_info = NULL;
                    break;
                }
     
                tmp++;
            }
        }
     
        return tab_info;
    }

    Ceci me semble effectivement mieux. Pourquoi allouer de la memoire pour un pointeur alors que l espace est deja alloue dans un tableau.

    Cela vous semble aussi meilleur ?

  12. #12
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Dark_Ebola
    a chaque malloc (ou calloc) correspond un free.
    Et dans le cadre d'un fork? Si l'on alloue de la mémoire, faut-il aussi la libérer dans les processus fils? En fait, je voudrais réutiliser dans un processus fils un pointeur qui a été alloué par le père. Et, pour cela, je voudrais le redimensionner afin de travailler avec la taille adéquate dans le processus fils.

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2003
    Messages
    878
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2003
    Messages : 878
    Points : 1 067
    Points
    1 067
    Par défaut
    Citation Envoyé par Dud225
    Et dans le cadre d'un fork? [...]
    Tu devrais créer un nouveau thread pour poser cette question.

    Note : quand j'écris "nouveau thread", je veux bien sûr dire "nouvelle discussion", ce n'est (presque) pas de jeu de mot avec fork()...

  14. #14
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    @nivose110 :

    Normalement tu devrais faire un free du tmp data avant de libérer tmp.
    Sauf qu'on ne sait pas ce qu'est ton data. Comme là tu assigne par une égalité, on doit supposer que c'est soit une valeur, soit un tableau alloué pour tmp, que tu affectes directement à la vraie structure. Et dans ce cas effectivement il ne faut pas le libérer.

    Citation Envoyé par Dud225
    Et dans le cadre d'un fork? Si l'on alloue de la mémoire, faut-il aussi la libérer dans les processus fils? En fait, je voudrais réutiliser dans un processus fils un pointeur qui a été alloué par le père. Et, pour cela, je voudrais le redimensionner afin de travailler avec la taille adéquate dans le processus fils.

    Et non.. le fils ne reçoit que quelques paramètres et contextes du père, mais pas les variables de ce style.

    Ce qu'il faut savoir de base c'est qu'un "fork" revient en fait à ré-éxécuter le main jusqu'à l'instruction fork, en la sautant, mais comme c'est un NOUVEAU processus il n'hérite que d'une partie de choses.

    Donc si tu fais une allocation avant d'avoir atteint le fork, cette allocation sera REPETEE (et non commune) dans le processus fils.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Pour être plus précis, fork() duplique complètement un processus et sa zone mémoire.
    Les zones allouées également sont dupliquées, donc le père ET le fils doivent libérer la leur.

  16. #16
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2006
    Messages : 35
    Points : 41
    Points
    41
    Par défaut
    OK. Et si je fais un execl dans le fils, je ne suis plus obligé de libérer les zones mémoires allouées dans le processus fils, si?

Discussions similaires

  1. [SQL2K]+[W2KServer] - QUESTION SUR LA MEMOIRE
    Par julien-sdis95 dans le forum MS SQL Server
    Réponses: 0
    Dernier message: 28/11/2007, 10h34
  2. Quelques questions sur le TWebBrowser...
    Par CorO dans le forum Web & réseau
    Réponses: 3
    Dernier message: 17/01/2003, 21h23
  3. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  4. Réponses: 2
    Dernier message: 11/08/2002, 21h27
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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