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 :

Manipulation de pointeur et structure dynamique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut Manipulation de pointeur et structure dynamique
    Bonjour tout le monde,
    Voilà, je suis en train d'essayer de créer une structure dynamique afin de stocker un tableau de structure, sachant que le nombre d'objet dans ce tableau doit pouvoir varier.

    Actuellement je n'en suis qu'à la manipulation des allocations et libérations.

    Voici le code :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    /* déclarations dans mon fichier d'en-tête */
     
    typedef struct{
    	unsigned int id;
    	char *content;
    } Row;
     
    typedef struct{
    	unsigned int count;
    	Row *rows;
    } Table;
     
    Table *newTable(void);
    void destroyTable(Table *aTable);

    Et ce que j'ai tenté de faire pour l'instant :

    Code C : 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
     
    /***************** CREATION ET DESTRUCTION ***************/
    Table *newTable(void)
    {
    	void *tmp = NULL;
    	tmp = malloc(sizeof(Table));
     
    	if (tmp != NULL)
    	{
    		Table *newTable = (Table *)tmp;
    		newTable->count = 0;
    		newTable->rows->id = 0;
    		newTable->rows->content = NULL;
    		return newTable;
    	}
    	else
    	{
    		return NULL;
    	}
    }
     
    void destroyTable(Table *aTable)
    {
    	unsigned int i = 0;
    	unsigned int count = countOfItemInTable(aTable); // déclaré dans le reste du code
    	for(i = 0;i < count;i++)
    	{
    		free(&aTable->rows[i].id);
     
    		aTable->rows[i].content = NULL; // avant ou apres free() ?
    		free(aTable->rows[i].content);
    	}
    	free(&aTable->count);
    	aTable = NULL;
    }

    Je suis bien conscient de ne pas encore savoir maitriser les allocations et désallocations, c'est bien pour ça que j'aimerais obtenir de l'aide.
    Pour cette structure dynamique, je tiens absolument à manipuler manuellement la mémoire de tous les éléments des structures.

    Merci et bon développement à tous

    P.S.: la question est : qu'est-ce qui ne va pas dans mon code ?

  2. #2
    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 Spootnik-Dev
    Actuellement je n'en suis qu'à la manipulation des allocations et libérations.
    <...>
    Pour cette structure dynamique, je tiens absolument à manipuler manuellement la mémoire de tous les éléments des structures.

    Merci et bon développement à tous

    P.S.: la question est : qu'est-ce qui ne va pas dans mon code ?
    Rien de va. A mon avis, tu devrais commencer par des choses plus simples.

    Creer un tableau dynamique à une dimension, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    /* tint.h */
    #include <stddef.h>
     
    struct tint;
     
    struct tint *tint_create(size_t size);
    void tint_delete(struct tint *);
    Essaye d'implémenter ça et de le tester. Pose des questions si nécessaire.

    Je veux bien te guider pas à pas.

  3. #3
    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
    Spootnik-Dev a écrit :
    la question est : qu'est-ce qui ne va pas dans mon code ?
    Ben plusieurs choses...

    1) tu n'initialises pas rows quand tu alloues table
    2) tu n'alloues pas les rows... donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            newTable->rows->id = 0;
            newTable->rows->content = NULL;
    est indéfini....

    3) Quand tu dis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	aTable->rows[i].content = NULL; // avant ou apres free() ?
    	free(aTable->rows[i].content);
    à ton avis ?

  4. #4
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut
    mais puiqu'au départ je n'ai aucun Row dans ma Table, je dois quand même l'initialiser ? rows est la liste de ma structure Table qui contiendra des éléments, mais uniquement après avoir demandé à en ajouter.
    Ou alors je laisse juste ça ?

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    newTable->rows = NULL;

    Citation Envoyé par souviron34
    3) Quand tu dis :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
         aTable->rows[i].content = NULL; // avant ou apres free() ?
         free(aTable->rows[i].content);
    à ton avis ?
    L'adresse mémoire doit être libérée avant d'être déréférencée, donc j'inverse les deux lignes si j'ai bien compris.

    Citation Envoyé par Adoz
    Je suppose que c'est lors de la destruction que ton problème survient.
    euh… même pas

  5. #5
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut
    J'ai modifié le code, j'espère que c'est un peu moins horrible.

    Code C : 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
     
    Table *newTable(void)
    {
    	void *tmp = NULL;
    	tmp = malloc(sizeof(Table));
     
    	if (tmp != NULL)
    	{
    		Table *newTable = (Table *)tmp;
    		newTable->count = 0;
     
    		return newTable;
    	}
    	else
    	{
    		return NULL;
    	}
    }
     
    void destroyTable(Table *aTable)
    {
    	unsigned int i = 0;
    	unsigned int count = countOfItemInTable(aTable);
    	for(i = 0;i < count;i++)
    	{
    		free(aTable->rows[i].content);
    		aTable->rows[i].content = NULL;
    		free(aTable->rows);
    		aTable->rows = NULL;
    	}
    	free(aTable);
    	aTable = NULL;
    }

    ça fonctionne correctement (ou du moins en apparence) mais je ne sais pas si tout est vraiment propre.

  6. #6
    Membre émérite Avatar de Ceylo
    Profil pro
    Étudiant
    Inscrit en
    Janvier 2007
    Messages
    1 216
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Par défaut
    Citation Envoyé par Adoz
    Il n'est pas nécessaire de faire tes "=NULL".
    Tu en es sûr ? Normalement si je ne le fais pas, après l'appel à free() mon pointeur pointe sur une adresse mémoire vide, donc si jamais j'essaie d'utiliser ce pointeur je risque d'avoir des problèmes non ?

  7. #7
    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
    @Spootnik

    OUI il faut que tu mettes dans la création :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    table->rows= NULL ;
    Ensuite dans la destruction AVANT de faire les free il faut t'assurer qu'il n'y pas de NULL :

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        if ( aTable->rows[i].content != NULL )
          {
    	free(aTable->rows[i].content);
    	aTable->rows[i].content = NULL;
          }
    Sinon crash...

    De plus je rappelle que quand on alloue de la place et que cela contiendra ou des caractères ou des pointeurs, il est plus facile de faire calloc que malloc, car alors tout ce qui a été alloué est initalisé à NULL.

    Sinon oui il est préférable et recommandé de ré-initialiser les pointeurs à NULL après avoir fait appel à free..

    Et en entrée de la routine de Destroy tu peux aussi tester si la table est pas déjà NULL... Au cas ou...

  8. #8
    Membre éclairé

    Inscrit en
    Février 2006
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 61
    Par défaut
    Bonjour,
    Je suppose que c'est lors de la destruction que ton problème survient. En fait, tu dois faire un free de de char* (content) en premier. Suite tu peux détruire ton tableau. Pas besoin de détruire l'id.

    Tu peux faire :
    free(aTable->rows[i]);

    Il n'est pas nécessaire de faire tes "=NULL".

    Normalement ça devrait aller mieux. Le plus simple est aussi de nous donner l'erreur que le compilateur t'envoi.

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

Discussions similaires

  1. Manipulation de pointeur sur tableau dynamique
    Par vincenet dans le forum Débuter
    Réponses: 12
    Dernier message: 09/12/2014, 17h53
  2. Réponses: 11
    Dernier message: 01/08/2010, 14h34
  3. [C++ .NET] Structure dynamique
    Par tidou dans le forum VC++ .NET
    Réponses: 17
    Dernier message: 29/10/2004, 20h08
  4. Réponses: 12
    Dernier message: 26/04/2004, 08h32
  5. probleme avec pointeurs de structures
    Par remi77 dans le forum C
    Réponses: 2
    Dernier message: 20/10/2003, 13h19

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