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 :

free() qui provoque une segmentation fault


Sujet :

C

  1. #1
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut free() qui provoque une segmentation fault
    bonjour a tous,

    j'ai une fonction free qui provoque une segmentation fault.
    Qu'en pensez vous ?
    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
    typedef struct S_BufferTile
    {
        SDL_Surface *image;
        enum tiles tileSymbol;
    }S_BufferTile;
     
    typedef struct S_BoxTile
    {
      S_BufferTile box;
      int xBoxPos;
      int yBoxPos;
      int state;
    }S_BoxTile;
     
    int main()
    {
       S_BoxTile *boxes;/*localisation des caisses dans le plateau*/
       boxes=initBox();/*cree un tableau de caisses*/
    ....
       freeBoxes(boxes);
    ...
     return EXIT_SUCCESS;
    }
     
    S_BoxTile* initBox(void)
    {
      /*initialisation des caisses du jeux*/
      S_BoxTile *boxes=(S_BoxTile*)malloc(MAX_BOX_LEVEL*sizeof(S_BoxTile));
     
      int i;
      for (i=0; i<MAX_BOX_LEVEL; i++)
        {
          boxes[i].box.image=NULL;
          boxes[i].box.tileSymbol=0;
          boxes[i].xBoxPos=0;
          boxes[i].yBoxPos=0;
        }
      return boxes;
     
    void freeBoxes(S_BoxTile *boxes)
    {
      /*libere les ressources allouee aux boites*/
      printf("boxes dans freeboxes=%p\n",boxes);
      free(boxes);
      boxes=NULL;
    }
    je ne comprends pas le pourquoi.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    En général, un free() qui provoque un plantage a 2 causes possibles :
    • Le double free(). Tu libères 2 fois le même bloc de mémoire.
    • Le bloc alloué est corrompu par le programme quand tu vas écrire plus loin que la taille demandée et en général, cela corromp un pointeur (et pas forcémment le pointeur courant).

    La correction de ce problème demande de remonter les manches et de tracer toutes les allocations/libérations ainsi que les lectures/écritures dans les blocs alloués.

    Il y a aussi des outils pour aider au débuggage (Valgrind ?)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci de ta reponse ram-0000

    lors du segment fault, j'ai remarquer ceci dans la console :

    boxes avant liberation=0x8d43750
    boxes dans freeboxes=0x8d43750
    *** glibc detected *** ./sokoban: munmap_chunk(): invalid pointer: 0x08d43750 ***

    la memoire alloue me renvoie 0x8d43750
    glibc detected : 0x08d43750 pourquoi 0x<0>8d...

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par bringer Voir le message
    la memoire alloue me renvoie 0x8d43750
    glibc detected : 0x08d43750 pourquoi 0x<0>8d...
    Si ton problème c'est le 0 supplémentaire affiché par glibc, ce n'est pas un problème. Toi tu fais un affichage sur 7 octets (0x8d43750), glibc préfère un affichage sur 8 octets (0x08d43750) en rajoutant un 0 supplémentaire devant (ce que je préfère aussi).

    Ce n'est absolumment pas la cause de ton problème.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci ram-0000

    l'erreur était effectivement due à une autre allocation dans une autre fonction.
    J'avais fait l'erreur de créer un tableau de structure avec une variable numérique au lieu d'une constante. Quand j'ai créer la constante pour plus de facilite, sur la ligne de l'allocation du tableau, j'ai laisser valeur numérique (3) au lieu de la remplacer par ma constante créé (#define MAX_TILE 5).

    du coup, lors du parcours du tableau, je séquençais sur 5 blocs structures mais je n'en avais alloué que 3, d'où segmentation fault.

    merci encore.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    void freeBoxes(S_BoxTile *boxes)
    {
    /*libere les ressources allouee aux boites*/
    printf("boxes dans freeboxes=%p\n",boxes);
    free(boxes);
    boxes=NULL;
    }
    Tu ne modifies ici que le pointeur local. Une fois que tu sors de la fonction, ton pointeur d'origine pointe toujours au même endroit qu'auparavant, ce qui est un bug.

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Le fait de mettre le pointeur à NULL est une sage précaution mais elle n'a d'intérêt que dans la fonction freeBoxes(). Le pointeur étant passé par valeur à la fonction, la valeur du pointeur dans l'appelant n'est pas modifiée.

    Il faudrait un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void freeBoxes(S_BoxTile **boxes)
    {
       /*libere les ressources allouee aux boites*/
       printf("boxes dans freeboxes=%p\n",*boxes);
       free(*boxes);
       *boxes=NULL;
    }
    pour que cela soit vraiment efficace.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Le fait de mettre boxes = NULL dans la fonction de libération de la mémoire est inutile, mais ce n'est pas un bug, tant que l'on ne teste pas si boxes est NULL à l'extérieur.
    Dans la fonction InitBoxes, il me parait indipensable de passer le nombre d'éléments en paramètre, c'est la seule chose qui justifie de faire une fonction, puisque la seule variable est justement le nombre d'éléments.
    D'autre part, il est bon que l'appel à free() soit fait au même niveau que l'appel à malloc().
    Voila comment j'aurais écrit cette séquence
    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
     
    int main()
    {
       S_BoxTile *boxes;/*localisation des caisses dans le plateau*/
       boxes=(S_BoxTile*)malloc(MAX_BOX_LEVEL*sizeof(S_BoxTile));
       initBox(S_BoxTile *boxes, MAX_BOX_LEVEL);/*initialise le tableau de caisses*/
    ....
       if (boxes)
       {
         printf("boxes dans freeboxes=%p\n",boxes);
         free(boxes);
         boxes=NULL;
       }
    ...
     return EXIT_SUCCESS;
    }
     
    void initBox(S_BoxTile *boxes, int  MAX_BOX_LEVEL)
    {
      /*initialisation des caisses du jeux*/
     
      int i;
      for (i=0; i<MAX_BOX_LEVEL; i++)
        {
          boxes[i].box.image=NULL;
          boxes[i].box.tileSymbol=0;
          boxes[i].xBoxPos=0;
          boxes[i].yBoxPos=0;
        }
    }
    /*   fonction inutile dans tous les cas
    void freeBoxes(S_BoxTile *boxes)
    {
      /*libere les ressources allouee aux boites*/
      printf("boxes dans freeboxes=%p\n",boxes);
      free(boxes);
      boxes=NULL;
    }
    */

  9. #9
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci de votre aide à tous.

    Ok, on libere au même niveau que celui où on a alloué. Je pensait passer par des fonctions pour un peu mieux découper le code et alléger la fonction de principale.
    Dans ce cas, que devrait t'il se passer après un free (sans avoir fait de boxes=NULL).
    Pour moi si je tente d'acceder à un élément de la structure, je devrait avoir un segfault... et bien non, compilateur n'a pas broncher et ma gentiment modifier ma valeur ?????
    Par contre après un boxes=NULL; , segfault, mais segfault également sans avoir free ce qui me semble logique car je dépointe l'adresse.

    Autre question, mais peut être devrais je créer une autre discussion.
    je voudrait utiliser un tableau de structure contenant un pointeur sur une structure.
    donc :
    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
     
    typedef struct S_BufferTile
    {
        SDL_Surface *image;
        enum tiles tileSymbol;
    }S_BufferTile;
    typedef struct S_BoxTile
    {
      S_BufferTile *box;
      int xBoxPos;
      int yBoxPos;
      int state;
    }S_BoxTile;
     
    int main()
    {
       S_BoxTile *boxes;
       boxes=(S_BoxTile*)malloc(MAX_BOX_LEVEL*(sizeof(S_BoxTile)));
       return EXIT_SUCCESS;
    }
     
    void initBox(S_BoxTile *boxes)
    {
      /*initialisation des caisses du jeux*/
      int i;
      if (boxes!=NULL)
        {
          for (i=0; i<MAX_BOX_LEVEL; i++)
    	{
    	  boxes[i].box->image=NULL;
    	}
      }
      else
      exit(0);
    }
    ne fonctionne pas.
    là aussi erreur de segmentation.

  10. #10
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Ton initBox() alloue ton tableau de structures S_BoxTile mais pour chaque structurez allouée, il faut aussi allouer une structure S_BufferTile sinon, crash lors de l'accès au membre box.

    Il ne faut pas non plus oublier de libérer cette structure S_BufferTile avant de libérer ton tableau de S_BoxTile sinon, fuite mémoire (c'est pas grave, mais c'est pas propre).

    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
    void initBox(S_BoxTile *boxes)
    {
      /*initialisation des caisses du jeux*/
      int i;
      if (boxes!=NULL)
        {
          for (i=0; i<MAX_BOX_LEVEL; i++)
    	{
                   boxes[i].box = malloc(sizeof(S_BufferTile));
                   boxes[i].box->tileSymbol = WellKnownValue; // sinon, initialisé avec n'importe quoi	
                   boxes[i].box->image=NULL;
    	}
      }
      else
      exit(0);
    }
    Il faut aussi rajouter un test sur la réussite du malloc du membre box (ce que je n'ai pas fais)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  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
    Dans ce cas, que devrait t'il se passer après un free (sans avoir fait de boxes=NULL).
    Pour moi si je tente d'acceder à un élément de la structure, je devrait avoir un segfault... et bien non, compilateur n'a pas broncher et ma gentiment modifier ma valeur ?????
    Le compilateur, lui, s'en moque. C'est à l'exécution qu'un problème peut se manifester. Utiliser une adresse après avoir fait un free() dessus conduit à un comportement imprévisible. Il peut ne rien se passer en apparence ou le programme peut planter (systématiquement ou de façon aléatoire, immédiatement ou plus tard ailleurs dans le code). On doit considérer que, dans ce cas, le programme est détruit, qu'il plante ou non.

    C'est d'ailleurs pourquoi on recommande de mettre le pointeur à NULL : (1) le programme peut tester si besoin que la mémoire est effectivement allouée et (2) si il ne le teste pas et ne fait pas l'allocation en croyant qu'elle a déjà été faite, on aura un plantage franc à un endroit précis du code et ce sera plus facile à dépanner
    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 habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci ram-000 pour la correction apportée au code.
    Après 1 ou 2 heures de pose, j'avais réussi enfin à détecter le problème et à le régler mais en statique en faisant une modification de ma structure en :
    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
     
    typedef struct S_BoxTile
    {
      S_BufferTile box[1];
      int xBoxPos;
      int yBoxPos;
      int state;
    }S_BoxTile;
     //puis en modifiant mon initialisation
    void initBox(S_BoxTile *boxes)
    {
      /*initialisation des caisses du jeux*/
      int i;
      printf("dans initBox boxes=%p\n",boxes);
      if (boxes!=NULL)
        {
          for (i=0; i<MAX_BOX_LEVEL; i++)
    	{
    	  boxes[i].box[0].image=NULL;
    	}
      }
      else
      exit(0);
    Par contre, dans le post de Pierre Dolez,
    D'autre part, il est bon que l'appel à free() soit fait au même niveau que l'appel à malloc().
    Dans ce cas, où le malloc des éléments de la structure S_BufferTile a été réaliser dans la fonction, comment doit-on gérer le free() du coup.
    Une allocation avec le free() de la structure parente dans le main, les autres allocations dans la fonction init????

    Ensuite merci à diogene pour ton explication du comportement du free().
    Quand j'ai fais les test, je modifiais ma stucture immédiatement après le free(), du coup, l'OS n'avait certainement pas le temps de réallouer cette zone mémoire pour une autre tache. Ce qui me donnais l'impression que le free() n'avait pas d'effet.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Je pense qu'il y a beaucoup de choses à dire.
    1- vous déclarez une structure S_BoxTile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct S_BoxTile
    {
      S_BufferTile box[1];
      int xBoxPos;
      int yBoxPos;
      int state;
    }S_BoxTile;
    Si vous déclarez box de type S_BufferTile [], cela signifie que la structure S_BoxTile contient un tableau de type S_BufferTile, puisqu'il n'y en a qu'un, pourquoi déclarer un tableau ?.

    2- L'utilité et le fonctionnement de malloc() .. free().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
      {
        UnType *Objet;
    //    N  le nombre d'objets à allouer
        Objet = (UnType*)malloc(sizoef(UnType) * N);
        ........
        traitement
        .........
        free(Objet);   //On libère la mémoire réservée à Objet, dans le même bloc
        //fin
      }
    Maintenant, supposons que l'initialisation de Objet nécessite de l'allocation mémoire, le code sera alors
    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
     
      {
        UnType *Objet;
    //    N  le nombre d'objets à allouer
        Objet = (UnType*)malloc(sizoef(UnType) * N);
        for (int i=0; i<N; i++)
        {
          InitObjet(Objet[i]);
        }
        ........
        traitement
        .........
        for (int i=0; i<N; i++)
        {
          FreeObjet(Objet[i]);
        }
        free(Objet);   //On libère la mémoire réservée à Objet, dans le même bloc
        //fin
      }
      void InitObjet(UnType *O)
      {
        O->Membre = (TypeMembre*)malloc(siezof(TypeMembre));
      }
      void FreeObjet(UnType *O)
      {
        free(O);
      }
    En partant de là il faut savoir ce que contient votre structure de base, puis comment vous organisez les différents objets correspondant à votre structure de base, et le tour est joué .

  14. #14
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    merci de votre reponse Pierre Dolez.

    effectivement je créé un tableau de 1 élément, c'est moyennement pertinent.
    En ce qui concerne l'allocation dynamique des sous structures par une fonction, là du coup je vois moins bien l'interet.
    Maintenant, je me demande comment, et il faudrait certainement que j'aille voir les sources, la librairie SDL procède.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //pour declarer une surface
    SDL_Surface *surface; //on a bien l'allocation dynamique d'un structure.
    //utilisation exemple:
    surface=SDL_CreateRGBSurface(....);
    //et liberation
    SDL_FreeSurface(surface);
    je trouve qu'au niveau syntaxique, mon code de départ ressemblait beaucoup à celui-ci. Encore une fois, sans avoir été fouiller dans les sources, j'ai le sentiment que la librairie a une fonction d'allocation de structure, et une autre fonction de libération, le tout avec un pointeur "simple" et pas un **surface qui nécessiterait un SDL_FreeSurface(&surface);
    Comment font-il?
    cordialement.

  15. #15
    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
    C'est un schéma classique : une fonction de création et une fonction de destruction. Simple et efficace !
    C'est le schéma utilisé pour le couple malloc() et free() étendu à des objets moins "élémentaires".

    Là, comme pour free(), il est laissé à la discrétion du programmeur de mettre ou non le pointeur (surface) à NULL après la libération (mais en tout cas de le considérer comme invalide).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  16. #16
    Invité
    Invité(e)
    Par défaut
    Bonjour Bringer,
    Naturellement votre code de départ ressemble beaucoup à l'exemple de surface, à la seule différence près, et elle est énorme que vous ne savez pas comment sont écrites les deux Foncrions Create...() et Free...().
    Dans mon exemple, les différentes opérations peuvent faire l'objet de 2 fonction, CreateBox() et FreeBox(), mais suivant un schéma strict.
    Ecrivez-le, testez-le et racontez-nous.

    A la dernière question, la réponse est de savoir si on crée UNE Surface ou UN TABLEAU de Surfaces.

    Cordialement.

    PS 1 Ne confondez surtout pas "syntaxique" et "logique"
    PS 2 Il n'est pas important de savoir comment "ils" font, mais comment vous devez faire.

  17. #17
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par diogene Voir le message
    Le compilateur, lui, s'en moque. C'est à l'exécution qu'un problème peut se manifester. Utiliser une adresse après avoir fait un free() dessus conduit à un comportement imprévisible. Il peut ne rien se passer en apparence ou le programme peut planter (systématiquement ou de façon aléatoire, immédiatement ou plus tard ailleurs dans le code). On doit considérer que, dans ce cas, le programme est détruit, qu'il plante ou non.

    C'est d'ailleurs pourquoi on recommande de mettre le pointeur à NULL : (1) le programme peut tester si besoin que la mémoire est effectivement allouée et (2) si il ne le teste pas et ne fait pas l'allocation en croyant qu'elle a déjà été faite, on aura un plantage franc à un endroit précis du code et ce sera plus facile à dépanner
    Le moyen le plus simple que je connaisse de vérifier que la mémoire (allocations/désallocations) est bien gérée, c'est... d'utiliser un outil de vérification de la gestion mémoire comme "purify" "insure" "valgrind"...

    )jack(

Discussions similaires

  1. [PHP 5.4] DateTime qui provoque une erreur 500 (incompréhensible)
    Par jb_gfx dans le forum Langage
    Réponses: 5
    Dernier message: 02/06/2013, 00h34
  2. Réponses: 2
    Dernier message: 18/03/2008, 13h58
  3. [C# 2.0] Un Convert.ToDouble qui semble provoque une exception.
    Par Pierre8r dans le forum Windows Forms
    Réponses: 1
    Dernier message: 25/05/2006, 16h51
  4. Syscall signal provoque un segmentation fault
    Par breezer911 dans le forum Administration système
    Réponses: 2
    Dernier message: 24/04/2006, 13h40
  5. Réponses: 6
    Dernier message: 13/11/2005, 12h11

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