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 :

Pb avec des fonctions pour libérer la mémoire


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Pb avec des fonctions pour libérer la mémoire
    Bonjour tout le monde voici mon problème:

    J'utilise pas mal d'allocations et réallocations mémoire dans mon code car je dois construire des tableaux 1D et 2D dont je ne connais pas à l'avance la taille. Et donc j'utilise aussi beaucoup de désallocations . pour éviter d'avoir à écrire à chaque fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int *p;
    ...
    free(p);
    p = NULL;
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int i;
    int** p;
    ...
    for(i = 0; i < nblignes; i++)
    {
          free(p[i]);
          p[i] = NULL;
    }
    free(p);
    p = NULL;
    j'utilise à la place deux fonctions qui vont me faire cette libération. voici ces deux fonctions :

    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
     
    void destroy1(int* p)
    {
    	if (p != NULL)
    	{
    		free(p);
    		p = NULL;
    	}
    }
     
    void destroy2(int** pp, int nbp)
    {
    	int i;
    	if(pp != NULL)
    	{
    		for(i = 0; i < nbp; i++)
    		{
    			if(pp[i] != NULL){
    				free(pp[i]);
    				pp[i] = NULL;
    			}
    		}
    		free(pp);
    		pp = NULL;
    	}
    }
    le problème c'est que ça n'a pas l'air de marcher ...

    quand je détruit un pointeur et que je teste s'il est égal à NULL, cela me renvoie 0.

    Peut être avez vous une idée sur ce problème.

    Merci d'avance

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Citation Envoyé par Krisprolls31 Voir le message
    le problème c'est que ça n'a pas l'air de marcher ... quand je détruit un pointeur et que je teste s'il est égal à NULL, cela me renvoie 0.
    C'est ambigü mais si, dans ton code, tu écris :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main (void)
    {
        int * p = NULL;
     
        p = malloc (50*sizeof(int));
        destroy (p);
     
        if (p==NULL) puts ("Mémoire libérée.");
     
        return 0;
    }

    … alors ça ne marchera pas comme tu l'entends. D'abord parce que tu ne détruis pas le pointeur, mais seulement la zone mémoire qu'il pointe. Ensuite, en appelant destroy(), tu passes par valeur le contenu du pointeur, c'est-à-dire l'adresse de la zone à libérer.

    L'argument « p » de ta fonction est vu comme une variable locale et est perdu à la sortie de ta fonction. En tout état de cause, il n'est pas lié à la variable « p » de ta fonction main() et tu ne peux donc pas changer la valeur de celle-ci depuis ta fonction.

    Si tu veux le faire, il faut remonter encore d'un niveau en passant à destroy() l'adresse de ton pointeur. Donc, un prototype de la forme « int ** » comme pour le tableau de pointeurs de destroy2().

    C'est un peu contraignant mais puisque tu as déjà écrit destroy2() et que tu t'en sers, tu peux utiliser la même fonction en considérant l'adresse de ton pointeur comme un tableau à une seule case :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main (void)
    {
        int * p = NULL;
    
        p = malloc (50*sizeof(int));
        destroy2 (&p,1);
    
        if (p==NULL) puts ("Mémoire libérée.");
    
        return 0;
    }

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci de ta réponse. j'ai modifié mes deux fonctions en passant en paramètre non plus un pointeur mais l'adresse de ce pointeur. et effectivement ça marche. Voici mes fonctions destroy :

    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
     
    void destroy1(int** p)
    {
    	if (*p != NULL)
    	{
    		free(*p);
    		*p = NULL;
    	}
    }
     
    void destroy2(int*** pp, int nbp)
    {
    	int i;
    	if(*pp != NULL)
    	{
    		for(i = 0; i < nbp; i++)
    		{
    			if((*pp)[i] != NULL){
    				free((*pp)[i]);
    				(*pp)[i] = NULL;
    			}
    		}
    		free(*pp);
    		*pp = NULL;
    	}
    }

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    C'est très bien. Si es perfectionniste, tu peux également vérifier si « p », en plus « de *p » n'est pas NULL également.

    À bientôt.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 18/03/2011, 16h10
  2. Compilation avec des fonctions virtuel pure
    Par vanitom dans le forum C++
    Réponses: 4
    Dernier message: 16/12/2005, 14h37
  3. tutoriel ou liste des fonctions pour GLADE
    Par debutanteVB.NET dans le forum GTK+ avec C & C++
    Réponses: 2
    Dernier message: 23/11/2005, 16h08
  4. Réponses: 6
    Dernier message: 23/05/2005, 15h38
  5. petit souci avec des variables avec des fonctions psql
    Par dust62 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/04/2005, 13h45

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