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 :

Problème struture - malloc


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 121
    Par défaut Problème struture - malloc
    Bonjour à tous !

    N'utilisant presque jamais le langage C je me retrouve avec un problème de base

    Voilà je souhaiterais créer :

    - une structure "piece" contenant un int couleur et un int "taille"
    - une structure "pile" contenant un int "position" et un tableau de pointeurs de pieces.

    Seulement voilà, j'arrive à créer des "piece", à afficher leurs contenus. Mais le problème est de créer une "pile" car je ne vois pas comment allouer la mémoire.

    voici mon code de "piece" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //le piece.h
    struct piece{
    	int taille; //nb etage
    	int couleur; //peut aussi correspondre au numero du joueur
    };
    typedef struct piece piece;
     
    piece *createPiece(int,int);
    void affichePiece_pt(piece*);
    void affichePiece_val(struct piece);
    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
     
    //le piece.c
    #include "piece.h"
     
    piece *createPiece(int t, int c){
    	piece *mapiece;
    	mapiece=(struct piece*)malloc(sizeof(struct piece));
    	mapiece->taille=t;
    	mapiece->couleur=c;
    	return mapiece;
    }
    void affichePiece_pt(piece *mapiece){
    	printf("taille=%d couleur=%d\n",mapiece->taille,mapiece->couleur);
    }
     
    void affichePiece_val(struct piece mapiece){
    	printf("taille=%d couleur=%d\n",mapiece.taille,mapiece.couleur);
    }
    Voici mon ébauche de "pile"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    //le pile.h
    struct pile{
    	piece **tab;
    	int position;
    };
    typedef struct pile pile;
     
    pile *createPile(int);
    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
     
    //le pile.c
    pile *createPile(int taille){
        pile *mapile;
        mapile=(pile*)malloc(taille*sizeof(pile));
    	mapile->tab=(piece**)malloc(taille*sizeof(piece*));
    	mapile->position=0;
    	return mapile;
    }
     
    void putPiece(pile *mapile,piece *mapiece){
    	int pos;
    	pos=mapile->position;
    	mapile->tab[pos]=mapiece;
    	mapile->position=pos+1;
    }
     
    void affichePile(pile *mapile){
    	int i,pos;
    	pos=mapile->position;
    	for(i=0;i<pos;i++){
    		affichePiece_pt(mapile->tab[i]);
    	}
    }
    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
     
    //le main de pile.c
    int main(int argc, char **argv){
        piece *mapiece1;
        piece *mapiece2;
        piece *mapiece3;
        piece *mapiece4;
    	pile *mapile;
     
    	printf("debut\n");
    	mapile=createPile(1);
     
    	mapiece1=createPiece(1,1);
    	affichePiece_pt(mapiece1);
     
    	mapiece2=createPiece(2,2);
    	affichePiece_pt(mapiece2);
     
    	mapiece3=createPiece(3,3);
    	affichePiece_pt(mapiece3);
     
    	mapiece4=createPiece(4,4);
    	affichePiece_pt(mapiece4);
     
    	printf("debut ajout\n");
     
    	putPiece(mapile,mapiece1);
            printf("ca devrait planter\n");
    	putPiece(mapile,mapiece2);
    	putPiece(mapile,mapiece3);
            putPiece(mapile,mapiece4);
     
    	affichePile(mapile);
    	printf("fin\n");
    	system("pause");
    	return 0;
    }
    si vous testez ça marche (en théorie) mais ça ne devrais aps car je créer une "pile" de 1 "piece" et je peux en ajouter presque autant que je veux.
    Je dois à coup sûr mal allouer (et sachant que la suite de mon projet repose sur des matrices de piles je peux pas me permettre de faire n'importe quoi).

    Si quelqu'un pouvait me donne la bonne méthodologie ! D'avance merci

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Déjà dans la fonction main createPile prévoit un seul piece. Il faut aussi penser à libérer la mémoire.

    La pile est soit assez grande au départ pour contenir tous ses éléments. Soit elle doit se retailler de manière dynamique.

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 121
    Par défaut
    Citation Envoyé par dj.motte
    Salut,

    Déjà dans la fonction main createPile prévoit un seul piece. Il faut aussi penser à libérer la mémoire.

    La pile est soit assez grande au départ pour contenir tous ses éléments. Soit elle doit se retailler de manière dynamique.
    ce que je veux montrer dans cet exemple c'est que je pense allouer correctement la mémoire et pourtant je n'ai pas de segmentation fault. Ma question n'est donc pas de réallouer en permanence la taille de pile car je la connaitrais.

    Donc ma question est : est-ce que je déclare tout correctement? si oui, pourquoi est-ce que je n'ai pas de segmentation fault?

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 121
    Par défaut
    d'ailleurs je viens de faire un test de ce genre :

    char *mon_string;
    mon_string=(char*)malloc(2*sizeof(char)+1);

    mon_string[0]='0';
    mon_string[1]='1';
    mon_string[2]='2';
    mon_string[3]='3';
    mon_string[4]='4';
    ...
    et ça marche .
    en théorie (char*)malloc(2*sizeof(char)+1) ne devrait-il pas être équivalent de char mon_string[2]; ?????

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par lamoua76
    Voilà je souhaiterais créer :

    - une structure "piece" contenant un int couleur et un int "taille"
    - une structure "pile" contenant un int "position" et un tableau de pointeurs de pieces.

    Seulement voilà, j'arrive à créer des "piece", à afficher leurs contenus. Mais le problème est de créer une "pile" car je ne vois pas comment allouer la mémoire.

    si vous testez ça marche (en théorie) mais ça ne devrais aps car je créer une "pile" de 1 "piece" et je peux en ajouter presque autant que je veux.
    Je dois à coup sûr mal allouer (et sachant que la suite de mon projet repose sur des matrices de piles je peux pas me permettre de faire n'importe quoi).

    Si quelqu'un pouvait me donne la bonne méthodologie ! D'avance merci
    Déjà, le code en pièce jointe a été réorganisé et complété pour compiler correctement.

    Il donne ceci (après instrumentation)

    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
     
    Usage xxx[ /T][ /E][ /O][ <options application>]
    FRMWRK.DBG_SYSALLOC=1
    SYSALLOC Overload (85 rec)
    SYSALLOC Successful initialization: 85 records available
    debut
    taille=1 couleur=1
    taille=2 couleur=2
    taille=3 couleur=3
    taille=4 couleur=4
    debut ajout
    ca devrait planter
    taille=1 couleur=1
    taille=2 couleur=2
    taille=3 couleur=3
    taille=4 couleur=4
    fin
    SYSALLOC min=4294967295 max=4294967295 delta=0
    SYSALLOC Err: Not-matched list:
    SYSALLOC Bloc 003D3C18 (8 bytes) malloc'ed at line 17 of 'pile.c' not freed
    SYSALLOC Bloc 003D2430 (4 bytes) malloc'ed at line 18 of 'pile.c' not freed
    SYSALLOC Bloc 003D2440 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Bloc 003D2450 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Bloc 003D2460 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Bloc 003D2470 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Released Memory
    FRMWRK.Termine
     
    Press ENTER to continue.
    Il y a donc un problème de libération de mémoire.

    ceci peut t'intéresser :

    http://emmanuel-delahaye.developpez.com/clib.htm
    Module SYSALLOC
    Fichiers attachés Fichiers attachés
    • Type de fichier : c main.c (920 octets, 68 affichages)
    • Type de fichier : c piece.c (600 octets, 64 affichages)
    • Type de fichier : h piece.h (397 octets, 67 affichages)
    • Type de fichier : c pile.c (697 octets, 71 affichages)
    • Type de fichier : h pile.h (455 octets, 61 affichages)

  6. #6
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 121
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il y a donc un problème de libération de mémoire.

    ceci peut t'intéresser :

    http://emmanuel-delahaye.developpez.com/clib.htm
    Module SYSALLOC
    merci pour l'analyse. Suite à la réponse de dj.motte j'ai écrit des fonctions de libération. Mais si je comprend bien, il est normal que mon programme fonctionne? Il est correctement écrit? car je pensais que si j'allouais ma pile pour 3 pieces, si j'en ajoutais une 4éme, il y aurait une segmentation fault. Apparement pas.

    Pour info voici mon code de libération de mémoire, je ne sais pas non plus si la méthodologie utilisée est correcte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //pour la piece
    void liberer_piece(piece *mapiece){
         free(mapiece);
    }
    //pour la pile
    void liberer_pile(pile *mapile){
         int i;
         for(i=0;i<mapile->taille;i++){
             liberer_piece(mapile->tab[i]);
             free(mapile->tab[i]);
         }
         free(mapile);
    }
    PS : je repose ma question concernant l'exemple sur le char * Merci !

  7. #7
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Dans la libération de la mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void liberer_pile(pile *mapile){
         int i;
         for(i=0;i<mapile->taille;i++){
             liberer_piece(mapile->tab[i]);  // une fois
             free(mapile->tab[i]);               // deux fois aieh ! 
         }
         free(mapile);
    }
    Pourquoi supprimer deux fois l'élément "piece" à l'indice i ? Je voyais plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void liberer_pile(pile *mapile)
    {  size_t  i;
         for( i =0 ; i<mapile->taille; i++)
         {   if( mapile->tab[i] )
             { free(mapile->tab[i]);
               mapile->tab[i] = 0 ;
             }
         }
         if( mapile ) 
         { free(mapile);
           mapile = 0 ;
         }
    }
    Pour les affectations hors d'une zone mémoire allouée, lorsqu'elles ne sont pas trop importantes, cela peut passer inaperçu pendant un certain temps à l'éxécution.

    D'où la nécessité de soumettre le programme à un debugger. Je me sers de valgrind avec linux.

    valgrind -v ./theprog

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par lamoua76
    merci pour l'analyse. Suite à la réponse de dj.motte j'ai écrit des fonctions de libération. Mais si je comprend bien, il est normal que mon programme fonctionne? Il est correctement écrit? car je pensais que si j'allouais ma pile pour 3 pieces, si j'en ajoutais une 4éme, il y aurait une segmentation fault. Apparement pas.
    Mais ça ne signifie pas que le code est correct.

    Il n'y a aucun contrôle de limites de tableaux en C. En cas de débordement, le comportement est indéfini. Tout peut arriver. C'est un bug. Il est de la responsabilité du programmeur d'écrire du code dont le comportement n'est jamais indéfini. Il faut ajouter les tests nécessaires.

    Pour info voici mon code de libération de mémoire, je ne sais pas non plus si la méthodologie utilisée est correcte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    //pour la piece
    void liberer_piece(piece *mapiece){
         free(mapiece);
    }
    //pour la pile
    void liberer_pile(pile *mapile){
         int i;
         for(i=0;i<mapile->taille;i++){
             liberer_piece(mapile->tab[i]);
             free(mapile->tab[i]);
         }
         free(mapile);
    }
    Ca me parait correct. Se méfier des apparences...

    Déjà, il a fallu que j'ajoute la taille dans la structure de pile. (elle va maintenant pouvoir servir à empêcher le débordement, mais je ne l'ai pas encore fait).

    En ajoutant uniquement le code de libération, on obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <...>
    SYSALLOC Err: Not-matched list:
    SYSALLOC Bloc 003D3C18 (4 bytes) malloc'ed at line 19 of 'pile.c' not freed
    SYSALLOC Bloc 003D2448 freed at line 50 of 'pile.c' not allocated
    SYSALLOC Bloc 003D2458 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Bloc 003D2468 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Bloc 003D2478 (8 bytes) malloc'ed at line 18 of 'piece.c' not freed
    SYSALLOC Released Memory
    FRMWRK.Termine
     
    Press ENTER to continue.
    Comment interpréter ceci :

    1 - Le tableau de pointeurs n'a pas été lbéré... (mapile->tab)
    2 - Comme l'a dit dj.motte, il y a 'double libération'.
    3,4,5 - Comme la pile a une taille de 1, les 3 autres éléments ('pièces') ne sont pas libérés. Le traitement doit être fait en amont. pas de place : on libère tout de suite.

    En corrigeant le problème de débordement, de double libération et en traitant l'erreur de 'mise en pile', on obtient :

    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
     
    Usage xxx[ /T][ /E][ /O][ <options application>]
    FRMWRK.DBG_SYSALLOC=1
    SYSALLOC Overload (85 rec)
    SYSALLOC Successful initialization: 85 records available
    debut
    taille=1 couleur=1
    taille=2 couleur=2
    taille=3 couleur=3
    taille=4 couleur=4
    debut ajout
    err=0
    ca devrait planter
    err=1
    err=1
    err=1
    taille=1 couleur=1
    fin
    SYSALLOC min=4294967295 max=4294967295 delta=0
    SYSALLOC All-matched
    SYSALLOC Released Memory
    FRMWRK.Termine
     
    Press ENTER to continue.
    Code corrigé en P.J.
    PS : je repose ma question concernant l'exemple sur le char *
    Je crois que tu as eu ta réponse...
    Fichiers attachés Fichiers attachés
    • Type de fichier : c main.c (1,4 Ko, 96 affichages)
    • Type de fichier : c piece.c (670 octets, 105 affichages)
    • Type de fichier : h piece.h (435 octets, 56 affichages)
    • Type de fichier : c pile.c (1,0 Ko, 66 affichages)
    • Type de fichier : h pile.h (492 octets, 73 affichages)

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Emmanuel va s'apercevoir que la fonction de libération de "mapile" de lamoua76 était scabreuse. C'était facile à deviner.

    Ouic ! Mon message s'est croisé avec celui d'Emmanuel.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte
    Salut,

    Emmanuel va s'apercevoir que la fonction de libération de "mapile" de lamoua76 était scabreuse. C'était facile à deviner.
    C'était vraiment très intéressant...

  11. #11
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Emmanuel,

    Une chose que je comprends pas dans ta fonction libérer pile .

    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
     
    void libererPile (pile * mapile)
     
    {
     
       int i;
     
       for (i = 0; i < mapile->taille; i++)
     
       {
     
          libererPiece (mapile->tab[i]);
     
       }
     
       free (mapile->tab);          /* -ed- */
     
       free (mapile);
     
    }
    C'est "free( mapile->tab );" .

    A mon avis cela ne sert à rien, mais je peux me tromper.

    Les éléments du tableau de pointeurs sont libérés par libererPiece. Une fois libérés, restent plus que les pointeurs à libérer par "free(mapile)".

    Je ne comprends pas bien ta démarche, en l'occurrence le "free(mapile->tab );".

    Je viens de vérifier, en fait tu as raison "free(mapile->tab);" est effectivement indispensable. J'ai consulté une de mes implémentations de tableau de pointeurs pour m'en rendre compte.

    Mais que penser de libererPile comme suit ?
    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
     
    void libererPile (pile * mapile)
    { int i;
     
       for (i = 0; i < mapile->taille; i++)
       {  if(  mapile->tab[ i ]  )
          { free(mapile->tab[ i ] );
            mapile->tab[ i ] = 0 ;
          }
       }
       if( mapile->tab) 
       { free (mapile->tab);    
         mapile->tab  = 0 ;
       }
       if( mapile )
       { free (mapile);
         mapile  =  0 ;
       }
    }

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    J'ai renforcé la sécurité du code de création et de suppression de la pile.
    Fichiers attachés Fichiers attachés
    • Type de fichier : c pile.c (1,3 Ko, 59 affichages)

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte
    Mais que penser de libererPile comme suit ?
    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
     
    void libererPile (pile * mapile)
    { int i;
     
       for (i = 0; i < mapile->taille; i++)
       {  if(  mapile->tab[ i ]  )
          { free(mapile->tab[ i ] );
            mapile->tab[ i ] = 0 ;
          }
       }
       if( mapile->tab) 
       { free (mapile->tab);    
         mapile->tab  = 0 ;
       }
       if( mapile )
       { free (mapile);
         mapile  =  0 ;
       }
    }
    Non Il faut d'abord commencer par tester mapile->tab. J'ai modifié le code en conséquence.

    Dans le contexte 'pointeur', 0 est correct, mais NULL est plus clair.

  14. #14
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Lorsque je fais free(z) j'ai l'habitude de faire après, z=0 ou NULL. Est-ce une mauvaise habitude ?

  15. #15
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    Dans cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void libererPile (pile * mapile)
    {
       if (mapile->tab != NULL)
       {
          int i;
          for (i = 0; i < mapile->taille; i++)
          {
             libererPiece (mapile->tab[i]);
          }
          free (mapile->tab);       /* -ed- */
       }
       free (mapile);
    }
    Si "mapile" est NULL ou 0, le dernier "free(mapile)" dans "libererPile" va planter. A moins que je ne connaisse pas bien le free du C.

    On ne peut pas faire un "free(0)" ou un "free(NULL)" en C, à ma connaissance, mais je peux me tromper.

  16. #16
    Membre confirmé
    Inscrit en
    Juillet 2006
    Messages
    121
    Détails du profil
    Informations forums :
    Inscription : Juillet 2006
    Messages : 121
    Par défaut
    Wahou ça c'est une communauté rapide !

    Merci à tous pour vos réponses et surtout pour vos explications !

    Je vais regarder et essayer de comprendre le code modifier par vos soins pour ne plus refaire les mêmes erreurs.

    Au fait, avec quoi vérifiez-vous les non libérations de mémoire? (ps : je suis sous win xp )

    Encore merci !

    PS : après un rapide coup d'oeil : pile *mapile = malloc (taille * sizeof mapile);
    pourquoi n'y-a-t- il pas de cast en (pile*) devant le malloc?

  17. #17
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par dj.motte
    Lorsque je fais free(z) j'ai l'habitude de faire après, z=0 ou NULL. Est-ce une mauvaise habitude ?
    Non bien au contraire. Au moins la valeur du pointeur indique clairement que ce pointeur n'est plus valide.

  18. #18
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par dj.motte
    Si "mapile" est NULL ou 0, le dernier "free(mapile)" dans "libererPile" va planter. A moins que je ne connaisse pas bien le free du C.

    On ne peut pas faire un "free(0)" ou un "free(NULL)" en C, à ma connaissance, mais je peux me tromper.
    Non, free(NULL) est tout afait valide (bien qu'inutile) et ne fais rien.

    Par contre le derefencement de mapile lui est une erreur.

  19. #19
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par lamoua76
    PS : après un rapide coup d'oeil : pile *mapile = malloc (taille * sizeof mapile);
    pourquoi n'y-a-t- il pas de cast en (pile*) devant le malloc?
    Parce qu'il n'est absolument pa utile en C.

  20. #20
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Salut,

    gl écrit :
    Non, free(NULL) est tout afait valide (bien qu'inutile) et ne fais rien.
    Ben moi qui me suis cassé la casserole, pour ne pas faire des dé-allocations sur un pointeur vide, je reste baba.

    Mes vieux compilateurs font une erreur à cet effet. J'ai toujours pris en C ( C++ aussi ) l'habitude de libérer la mémoire là où les quantités rejoignent l'équilibre.

    Sur mes anciennes versions du C, et des compilateurs la version "free(NULL)" provoquait une erreur. Dieu soit l'est il n'en est plus ainsi.

    Que donnerait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char * z = (char*) malloc( sizeof( NULL ) ) ;
    Peut-être un truc qui fait mal au système ?

    Je vais essayer. Je déconnecte, puis je reprendrai après les essais.

Discussions similaires

  1. problème avec malloc
    Par cyril_sy dans le forum C
    Réponses: 13
    Dernier message: 12/05/2007, 13h49
  2. Problème avec malloc et autre
    Par ego dans le forum C
    Réponses: 5
    Dernier message: 02/05/2007, 18h29
  3. probléme avec malloc
    Par tomasi dans le forum C
    Réponses: 18
    Dernier message: 15/11/2006, 15h15
  4. Problème avec malloc
    Par f56bre dans le forum C
    Réponses: 11
    Dernier message: 13/11/2006, 14h36
  5. Problème avec malloc.
    Par kmitz dans le forum C
    Réponses: 2
    Dernier message: 25/03/2006, 18h05

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