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 :

gestion mémoire sur plusieurs malloc


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut gestion mémoire sur plusieurs malloc
    Bonjour,

    Je voudrais savoir si vous avez des methodes pour gérer les malloc et leurs tests si ils echouent.

    Voici un exemple que j'ai écrit pour 3 pointeurs a allouer. Il me semble que ce code est "sur" dans le sens ou on ne peut pas perdre de mémoire, mais on voit que ca peut devenir vite lourd à gerer, surtout si on en a plus que 3, mais c'est la manière la plus simple et concise que j'ai trouvé pour l'instant :

    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
     
    int * a, *b;
    int ** c;
     
    a = malloc(taille);
    b = malloc(taille);
    c = malloc(taille2);
     
    if(a == NULL || b == NULL || c == NULL) {
    	free(a);
    	free(b);
    	free(c);
    	return -1;
    }
     
    //je met tout à null pour pouvoir faire un free sur tous au cas ou un échoue.
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = NULL;
    }
     
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = malloc(taille);
    	if( c[i] == NULL) {
    		free(a);
    		free(b);
    		for(i = 0 ; i < taille2 ; i++) {
    			free(c[i]);
    		}
    		free(c);
    		return -1;
    	}
    }
     
    //ouf tous les mallocs ont fonctionnés :roll:
     
    //on peut maintenant ecrire le reste de la fonction sans oublier de faire un free pour tous les pointeurs a la fin

  2. #2
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a = malloc(taille);
    b = malloc(taille);
    c = malloc(taille2);
     
    if(a == NULL || b == NULL || c == NULL) {
    	free(a);
    	free(b);
    	free(c);
    	return -1;
    }
    Ceci est correct. On peut faire free(NULL) en toute sécurité

    Tu peux te dispenser de la mise à NULL préalable des c[i] :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
    	c[i] = malloc(taille);
    	if( c[i] == NULL) {
    ...
    		for(j = 0 ; j < i ; j++) free(c[j]);
    ....
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  3. #3
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Arrete de poster n'importe quoi, ou bien pose des questions !!!!

    Ton code cointient au moins 4 raisons de crasher sans avertissement,....

    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
    int * a, *b;
    int ** c;
     
    a = malloc(taille);
    b = malloc(taille);
    c = malloc(taille2);
     
    if(a == NULL || b == NULL || c == NULL) {
    /**** OU SONT LES TESTS POUR SAVOIR LEQUEL EST NULL ??? ****/
    	free(a);
    	free(b);
    	free(c);
    	return -1;
    }
     
    //je met tout à null pour pouvoir faire un free sur tous au cas ou un échoue.
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = NULL;
    }
     
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = malloc(taille);
    	if( c[i] == NULL) {
    		free(a);
    		free(b);
    /**** DE i A taille2 IL N'Y A RIEN D'ALLOUE !!!!!! ****/
    		for(i = 0 ; i < taille2 ; i++) {
    			free(c[i]);
    		}
    		free(c);
    		return -1;
    	}
    }
     
    //ouf tous les mallocs ont fonctionnés :roll:
     
    //on peut maintenant ecrire le reste de la fonction sans oublier de faire un free pour tous les pointeurs a la fin
    Une bonne maniere de faire serait :

    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
    int j ;
    int * a=NULL, *b=NULL;
    int ** c=NULL;
     
    a = malloc(taille);
    b = malloc(taille);
    c = malloc(taille2);
     
    if(a == NULL || b == NULL || c == NULL) {
             if ( a != NULL )
    	free(a);
             if ( b != NULL )
    	free(b);
             if ( c != NULL )
    	free(c);
    	return -1;
    }
     
    //je met tout à null pour pouvoir faire un free sur tous au cas ou un échoue.
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = NULL;
    }
     
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = malloc(taille);
    	if( c[i] == NULL) {
    		free(a);
    		free(b);
                             if ( i != 0 )
      		  for(j = (i-1) ; j >= 0 ; j--) {			free(c[j]);
    		}
    		free(c);
    		return -1;
    	}
    }
     
    //ouf tous les mallocs ont fonctionnés :roll:
     
    //on peut maintenant ecrire le reste de la fonction sans oublier de faire un free pour tous les pointeurs a la fin
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Arrete de poster n'importe quoi, ou bien pose des questions

    Ton code contient au moins 4 raisons de crasher sans avertissement,....
    Pas la peine de s'énerver... mon code ne crashe pas car il n'y a pas besoin de tester lequel est à NULL vu qu'on peut faire free(NULL) (cf man free)

    Meme explication pour ta deuxième phrase en rouge -> j'avais initialisé a null

    Quand à "ou bien pose des questions", j'en ai posé une : c'est comment rendre ca moins lourd à gerer... je demande vos méthode pour ce genre de choses...

    Tu a sans doute mal lu mon post

  5. #5
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par diogene Voir le message
    On peut faire free(NULL) en toute sécurité
    pas sur tous les systemes... HPUX et SunOs crashent... (enfin crashaient il y a 6 ans)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  6. #6
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    et pour eviter de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = NULL;
    }
    il suffirait de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    c = calloc ( taille2, sizeof(int *) );

    Et d'ailleurs tes pointeurs sont declares comme des entiers (pointeurs), mais tu alloues des bytes...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    J'ai toujours lu dans man free
    Si ptr est NULL, aucune tentative de libération n'a lieu.
    donc j'utilise cette propriété.
    Si ça ne marche pas sur tous les sytemes, je ne le savais pas, mais ça change pas trop ma question d'origine qui est :

    Je voudrais savoir si vous avez des methodes pour gérer les malloc et leurs tests si ils echouent.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Et d'ailleurs tes pointeurs sont declares comme des entiers (pointeurs), mais tu alloues des bytes...
    Oui mais c'etait pour simplifier le code je ne fait pas ca dans un vrai code.
    J'aurai fait a = malloc (taille*sizeof(*a))
    Cet exemple était pour illustrer la lourdeur d'allouer plusieurs zones memoires sans risquer de fuites en cas d'echec.

  9. #9
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    faire du code resistant a tout signifie en general au moins 50% de code pour gerer les erreurs !!!!!
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Un système qui crashe sur un free(NULL) ne respecte pas la norme du C ANSI.

    Donc, sur tout système au moins respectueux du standard C90 (voire C89), free(NULL) est garanti ne pas crasher.
    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.

  11. #11
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    pas sur tous les systemes... HPUX et SunOs crashent... (enfin crashaient il y a 6 ans)
    Je me réfère aux bons auteurs :

    n1124 me dit
    7.20.3.2 The free function
    Synopsis
    1 #include <stdlib.h>
    void free(void *ptr);
    Description
    2 The free function causes the space pointed to by ptr to be deallocated, that is, made
    available for further allocation. If ptr is a null pointer, no action occurs....
    alors, moi je la crois!
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    faire du code resistant a tout signifie en general au moins 50% de code pour gerer les erreurs !!!!!
    oui, mais bon je me dit qu'il doit bien y avoir une maniere plus simple de gerer ce genre de cas.
    Car si on a n zones mémoire à allouer (dont certaines avec des allocations d'allocations), alors pour gerer la liberation des zones non alloués si ca foire en plein milieu, c'est pas 50% mais 99% de code pour gerer les erreurs si n est assez grand.

  13. #13
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    oui, mais bon je me dit qu'il doit bien y avoir une maniere plus simple de gerer ce genre de cas.
    Car si on a n zones mémoire à allouer (dont certaines avec des allocations d'allocations), alors pour gerer la liberation des zones non alloués si ca foire en plein milieu, c'est pas 50% mais 99% de code pour gerer les erreurs si n est assez grand.
    si tu en as autant et que ce n'est pas en tableau, alors c'est sans doute une erreur de conception..

    Sinon eh bien oui, cela peut etre 99% du code d'une fonction...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  14. #14
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Un système qui crashe sur un free(NULL) ne respecte pas la norme du C ANSI.

    Donc, sur tout système au moins respectueux du standard C90 (voire C89), free(NULL) est garanti ne pas crasher.
    Citation Envoyé par diogene Voir le message
    Je me réfère aux bons auteurs :

    n1124 me dit


    alors, moi je la crois!
    essaye sur un HPUX 10.2 ... ou un serveur HP K(230 ??), ou une station SGI Irix Indigo de 1997..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  15. #15
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    et pour eviter de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    for(i = 0 ; i < taille2 ; i++) {
    	c[i] = NULL;
    }
    il suffirait de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    c = calloc ( taille2, sizeof(int *) );

    Et d'ailleurs tes pointeurs sont declares comme des entiers (pointeurs), mais tu alloues des bytes...
    calloc ne garantis pas la mise à NULL ...enfin c'est ce que j'ai compris en lisant les nombreux postes traitant du "all bits zero" et de cette fameuse "trap representation" ....peut être que je me trompe c'est plus une confirmation que j'attends
    To start press any key. (reading screen) Where's the "any" key? I see Esc, Catarl, and Pig Up. There doesn't seem to be any "any" key. Wo! All this computer hacking is making me thirsty. I think I'll order a Tab. (presses TAB key). -- HOMER --

  16. #16
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Une bonne maniere de faire serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int j ;
    int * a=NULL, *b=NULL;
    int ** c=NULL;
     
    a = malloc(taille);
    b = malloc(taille);
    c = malloc(taille2);
    Euh, il n'y a pas de différence entre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    T *p;
     
       p = malloc(...);
    ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    T *p = NULL;
     
       p = malloc(...);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    T *p = malloc(...);
    Personnellement, la 3ème forme a ma préférence...

    Citation Envoyé par souviron34 Voir le message
    pas sur tous les systemes... HPUX et SunOs crashent... (enfin crashaient il y a 6 ans)
    Non conformité au langage C ? C'est grave...

    Citation Envoyé par souviron34 Voir le message
    faire du code resistant a tout signifie en general au moins 50% de code pour gerer les erreurs !!!!!
    +1

    Citation Envoyé par pasdeface Voir le message
    Je voudrais savoir si vous avez des methodes pour gérer les malloc et leurs tests si ils echouent.
    Dans un premier temps, je fais comme ça :
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #include <stdlib.h>
    #include <assert.h>
     
    int main (void)
    {
       int taille = 3;
       int taille2 = 4;
     
       int *a = malloc (taille * sizeof *a);
       if (a != NULL)
       {
          int *b = malloc (taille * sizeof *b);
          if (b != NULL)
          {
             int **c = malloc (taille2 * sizeof *c);
             if (c != NULL)
             {
     
    /* je met tout à null pour pouvoir faire
    un free sur tous au cas ou un échoue. */
                {
                   int i;
                   for (i = 0; i < taille2; i++)
                   {
                      c[i] = NULL;
                   }
                }
     
                {
                   int err = 0;
                   {
                      int i;
                      for (i = 0; !err && i < taille2; i++)
                      {
                         c[i] = malloc (taille * sizeof *c[i]);
                         if (c[i] == NULL)
                         {
                            err = 1;
                         }
                      }
                   }
                   if (err)
                   {
                      /* tout liberer */
                      int i;
                      for (i = 0; i < taille2; i++)
                      {
                         free (c[i]);
                      }
                      free (c), c = NULL;
                      free (b), b = NULL;
                      free (a), a = NULL;
                   }
                }
     
                /* usage */
     
                /* liberation */
                {
                   int i;
                   for (i = 0; i < taille2; i++)
                   {
                      free (c[i]);
                   }
                   free (c), c = NULL;
                }
             }
             free (b), b = NULL;
     
             assert (c == NULL);
          }
          free (a), a = NULL;
     
          assert (b == NULL);
       }
       assert (a == NULL);
     
       return 0;
    }
    Mais dans la vraie vie, ce serait évidemment différent :
    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
     
    /* main.c */
    #include <stdlib.h>
     
    #include "x.h"
     
    int main (void)
    {
       /* creation */
       struct x *p = x_create (3, 4);
     
       if (p != NULL)
       {
          /* usage */
     
          /* liberation */
          x_delete (p);
       }
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /* x.h */
    #ifndef H_ED_X_20080222035637
    #define H_ED_X_20080222035637
     
    struct x;
     
    struct x *x_create(int taille, int taille2);
    void x_delete(struct x *self);
     
    #endif /* guard */
     
    /* Guards added by GUARD (c) ED 2000-2005 Jan 17 2005 Ver. 1.7 */
    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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    /* x.c */
    #include "x.h"
     
    #include <stdlib.h>
     
    struct x
    {
       int *a;
       int *b;
       int **c;
       int taille2;
    };
     
    struct x *x_create (int taille, int taille2)
    {
       struct x *self = malloc (sizeof *self);
       if (self != NULL)
       {
          /* tout a 0 */
          {
             static const struct x z = { 0 };
             *self = z;
          }
     
          self->a = malloc (taille * sizeof *self->a);
          if (self->a != NULL)
          {
             self->b = malloc (taille * sizeof *self->b);
             if (self->b != NULL)
             {
                self->c = malloc (taille2 * sizeof *self->c);
                if (self->c != NULL)
                {
     
    /* je met tout à null pour pouvoir faire
    un free sur tous au cas ou un échoue. */
                   {
                      int i;
                      for (i = 0; i < taille2; i++)
                      {
                         self->c[i] = NULL;
                      }
                   }
     
                   {
                      int err = 0;
                      {
                         int i;
                         for (i = 0; !err && i < taille2; i++)
                         {
                            self->c[i] = malloc (taille * sizeof *self->c[i]);
                            if (self->c[i] == NULL)
                            {
                               err = 1;
                            }
                         }
                      }
                      if (err)
                      {
                         x_delete (self), self = NULL;
                      }
                      else
                      {
                         self->taille2 = taille2;
                      }
                   }
                }
                else
                {
                   x_delete (self), self = NULL;
                }
             }
             else
             {
                x_delete (self), self = NULL;
             }
          }
          else
          {
             x_delete (self), self = NULL;
          }
       }
       return self;
    }
     
    void x_delete (struct x *self)
    {
       if (self != NULL)
       {
          if (self->c != NULL)
          {
             /* tout liberer */
             int i;
             for (i = 0; i < self->taille2; i++)
             {
                free (self->c[i]);
             }
             free (self->c);
          }
          free (self->b);
          free (self->a);
          free (self);
       }
    }
    Pas de Wi-Fi à la maison : CPL

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    merci

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    Me revoilà.

    Emmanuel Delahaye, ton exemple me plait beaucoup mais j'ai du mal a le comprendre.

    Pourquoi les membres de struct x sont défnis dans x.c ?
    Comment on peut accéder aux membres de p (de type struct x) dans le main ?

    merci

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Justement, avec un Type Abstrait de Données (TAD), on n'y accède pas. On peut seulement appeler des fonctions qui y accèdent, et qui sont elles aussi définies dans x.c.
    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.

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Points : 406
    Points
    406
    Par défaut
    ha, c'est un équivalent des classes en c++?

Discussions similaires

  1. Question sur la gestion mémoire
    Par rem02 dans le forum Langage
    Réponses: 7
    Dernier message: 06/01/2007, 22h06
  2. [Session] Problème de gestion sur plusieurs pages
    Par GLDavid dans le forum Tomcat et TomEE
    Réponses: 8
    Dernier message: 11/10/2006, 16h02
  3. Réponses: 4
    Dernier message: 25/11/2005, 18h15
  4. [Gestion mémoire] SetLength sur TDoubleDynArray
    Par MD Software dans le forum Langage
    Réponses: 14
    Dernier message: 24/04/2005, 21h11
  5. Gestion de la mémoire entre plusieurs DLL
    Par Laurent Gomila dans le forum C++
    Réponses: 7
    Dernier message: 27/07/2004, 15h28

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