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 :

Structure en C : Allocation et désallocation propre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut Structure en C : Allocation et désallocation propre
    Bonjour,

    Je revisite un peu le langage C, étant plus connaisseur de la programmation objet C#.

    je travaille avec les structure en C sur un petit projet de jeu en SDL (rien de bien exceptionnel). cependant je me pose la question de comment bien rendre la mémoire au système pour éviter les "memory leak".

    Voici le bout de code que j'utilise pour déclarer, affecter et utiliser ma structure. J'aimerais savoir si cela est correct en terme de gestion de mémoire particulièrement le dernier volet.

    Merci de vos commentaires et de toute aide que vous pourrez me donner.

    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
     
    //DECLARATION DE MA STRUCTURE 
    typedef struct SpriteStruct {
    char                     NumerOfLife;
    unsigned short           Xlocation;
    unsigned short           Ylocation;
    char                     Energy;
    unsigned short           *XframeLocation;
    unsigned short           *YframeLocation;
    char                     *Hframe;
    char                     *Lframe;
    SDL_Surface              *surface;
    };
     
    //MISE EN PLACE DES TABLEAUX
    unsigned short *xframeLocation= (unsigned short *) malloc(10 * sizeof(unsigned short));
    unsigned short *yframeLocation= (unsigned short *) malloc(10 * sizeof(unsigned short));
    unsigned short *hframe= (unsigned short *) malloc(10 * sizeof(unsigned short)); 
    unsigned short *lframe= (unsigned short *) malloc(10 * sizeof(unsigned short));
    heroSurface = SDL_LoadBMP("hero.bmp");
     
    //INSTANCIATIOn
    struct SpriteStruct hero;
     
    //AFFECTATION
    hero.NumerOfLife=3;
    hero.Xlocation=0;
    hero.Ylocation=320;
    hero.Energy=255;
    hero.XframeLocation=xframeLocation;
    hero.YframeLocation=yframeLocation;
    hero.Hframe=hframe;
    hero.Lframe=lframe;
    hero.surface=heroSurface;
     
    //TRAITEMENTS
    ......
     
    //DESALOCATION
    free(hero.XframeLocation);
    free(hero.YframeLocation);
    free(hero.Hframe);
    free(hero.Lframe);
    SDL_FreeSurface(hero.surface);
    free(hero);

  2. #2
    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
    déjà tu as une erreur (énorme) de définiton d'un type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct SpriteStruct {
    char                     NumerOfLife;
    unsigned short           Xlocation;
    unsigned short           Ylocation;
    char                     Energy;
    unsigned short           *XframeLocation;
    unsigned short           *YframeLocation;
    char                     *Hframe;
    char                     *Lframe;
    SDL_Surface              *surface;
    };
    ne définit pas une structure, ou plutôt elle en défini une, mais non utilisable, car là tout ce que tu as défini est un tag sur une structure...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct tag { ...} nameofstruct ;

  3. #3
    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
    Disons, qu'elle déclare un structure accessible comme struct SpriteStruct et que le typedef ne sert à rien.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Merci déjà de cette remarque très pertinente : j'ai corrigé le problème de syntaxe !

    Cela nous donne :
    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
     
    //DECLARATION DE MA STRUCTURE 
    typedef struct SpriteTag {
    char                     NumerOfLife;
    unsigned short           Xlocation;
    unsigned short           Ylocation;
    char                     Energy;
    unsigned short           *XframeLocation;
    unsigned short           *YframeLocation;
    char                     *Hframe;
    char                     *Lframe;
    SDL_Surface              *surface;
    } SpriteStruct ;
     
    //MISE EN PLACE DES TABLEAUX
    unsigned short *xframeLocation= (unsigned short *) malloc(10 * sizeof(unsigned short));
    unsigned short *yframeLocation= (unsigned short *) malloc(10 * sizeof(unsigned short));
    unsigned short *hframe= (unsigned short *) malloc(10 * sizeof(unsigned short)); 
    unsigned short *lframe= (unsigned short *) malloc(10 * sizeof(unsigned short));
    heroSurface = SDL_LoadBMP("hero.bmp");
     
    //INSTANCIATION
    struct SpriteStruct hero;
     
    //AFFECTATION
    hero.NumerOfLife=3;
    hero.Xlocation=0;
    hero.Ylocation=320;
    hero.Energy=255;
    hero.XframeLocation=xframeLocation;
    hero.YframeLocation=yframeLocation;
    hero.Hframe=hframe;
    hero.Lframe=lframe;
    hero.surface=heroSurface;
     
    //TRAITEMENTS
    ......
     
    //DESALOCATION
    free(hero.XframeLocation);
    free(hero.YframeLocation);
    free(hero.Hframe);
    free(hero.Lframe);
    SDL_FreeSurface(hero.surface);
    free(hero);

  5. #5
    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
    1- le code exécutable en C doit être placé dans une fonction. Ce n'est pas le cas ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned short *xframeLocation= (unsigned short *) malloc(10 * sizeof(unsigned short));
    // et la suite
    2- xframeLocation (et les autres qui suivent) n'est pas défini, c'est en tant que membre d'une structure qu'il est défini

    3- Pourquoi des unsigned short et pas des char si on suit la définition de la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned short *hframe= (unsigned short *) malloc(10 * sizeof(unsigned short)); 
    unsigned short *lframe= (unsigned short *) malloc(10 * sizeof(unsigned short));
    3- heroSurface n'est pas défini ici. La variable doit être définie avant d'être utilisée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    heroSurface = SDL_LoadBMP("hero.bmp");
    4-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    struct SpriteStruct hero;
    ...
    free(hero);
    hero n'a pas été obtenu par allocation dynamique et ne doit pas être détruite par free()

    5 - On peut donc avoir quelque chose du genre :

    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
    //DECLARATION DE MA STRUCTURE 
    typedef struct SpriteStruct {
        char  NumerOfLife;
    //.....
        SDL_Surface  *surface;
    } SpriteStruct;
     
    //... fonction(....)
    {
       SpriteStruct hero;
       hero.NumerOfLife=3;
       hero.Xlocation=0;
       hero.Ylocation=320;
       hero.Energy=255;
       hero.XframeLocation = malloc(10 * sizeof(unsigned short));
       hero.YframeLocation = malloc(10 * sizeof(unsigned short));;
       hero.Hframe = malloc(10);
       hero.Lframe = malloc(10);
       hero.surface = SDL_LoadBMP("hero.bmp");
    // vérifier que toutes ces allocations ont réussi
    // Traitement si tout est OK....
       free(hero.XframeLocation);
       free(hero.YframeLocation);
       free(hero.Hframe);
       free(hero.Lframe);
       SDL_FreeSurface(hero.surface);
    }

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 66
    Par défaut
    Merci beaucoup, ça m'éclaire énormément.

    Une dernière chose avant de clore cette discussion.

    Il me reste a savoir comment les allocations se sont bien faites.

    Visiblement, les pointeurs référencent une zone mémoire où avant allocation il pourrait y avoir n'importe quoi. Comment discerner que ce qui est présent dans l'espace mémoire après allocation est correct ?

    Merci

  7. #7
    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
    Il me reste a savoir comment les allocations se sont bien faites.
    En cas d'échec de l'allocation, les fonctions d'allocation retournent NULL.

    Visiblement, les pointeurs référencent une zone mémoire où avant allocation il pourrait y avoir n'importe quoi. Comment discerner que ce qui est présent dans l'espace mémoire après allocation est correct ?
    Après une allocation (réussie) avec malloc(), la zone allouée contient ... n'importe quoi. Si on utilise calloc(), la zone allouée contient des 0.

  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
    il y a 2 élements :

    • Primo s'assurer que l'allocation s'est bien passée

      Dans ce qu'a cité diogene, il faut ajouter la vérification :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
         if ( (hero.XframeLocation = malloc(10 * sizeof(unsigned short))) == NULL )
            {
                fprintf ( stderr, "Erreur d'allocation !!\n");
                ....
            }

    • Secondo, ce que fait l'alloction est simplement réserver une certaine zone à partir d'une certaine adresse.

      Donc avant l'utilisation il y a n'importe quoi à cet emplacement.

      Si ce sont des variables typées normalement (integer, double, float, structures, etc, ), une simple assignation assignera tous les bits correspondants.

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      int i = 4, j ;
      struct MaStruct = {0}, MaStruct1;
       
      j = i ;
      MaStruct1 = MaStruct ;
      Dans le cas d'une chaîne (un tableau de char), une manière sûre est soit d'intialiser manuellement chacun des élements, soit (ce qu'on fait en général) d'initialiser simplement la chaîne (strcpy ( chaine, "");). Si cependant une utilisation caractère par caractère de la chaîne est faite, sans être sûr de passer par des fonction de copie de chaîne (strcpy, strup, sprintf, etc), alors une assignation caractère par cractère sera nécessaire.



    Note :

    Je rajouterais effectivement suite à la dernière remarque de digoene que c'est une raison pour laquelle je n'utilise jamais malloc mais plutôt calloc..

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  2. Réponses: 6
    Dernier message: 24/03/2006, 18h24
  3. allocation/désallocation de mémoire
    Par kinta dans le forum C++
    Réponses: 2
    Dernier message: 10/02/2006, 09h52
  4. Allocation dynamique de structures
    Par fr_knoxville dans le forum C
    Réponses: 8
    Dernier message: 06/05/2003, 21h59
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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