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

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    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 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 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.
    Pas de Wi-Fi à la maison : CPL

  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
    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 ?
    "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 habitué

    Inscrit en
    Février 2006
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 61
    Points : 142
    Points
    142
    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.
    Vous êtes passionné de nouvelles technologies?
    - Visitez : http://www.loicbar.com
    - Abonnez-vous : http://feeds.feedburner.com/Loicbarcom

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    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

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    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.

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    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 ?

  8. #8
    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
    @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...
    "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

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Voilà je crois que c'est plus propre maintenant. Si vous voyez une erreur, ou un cas que je n'ai pas prévu, n'hésitez pas .

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    Table *newTable(void)
    {
         void *tmp = NULL;
         tmp = malloc(sizeof(Table));
     
         if (tmp != NULL)
         {
              Table *newTable = (Table *)tmp;
              newTable->count = 0;
              newTable->rows = NULL;
     
              return newTable;
         }
         else
         {
              return NULL;
         }
    }
     
    void destroyTable(Table *aTable)
    {
         if (aTable != NULL)
         {
              if (aTable->rows != NULL)
              {
                   unsigned int i = 0;
                   unsigned int count = countOfItemInTable(aTable);
                   for(i = 0;i < count;i++)
                   {
                        if (aTable->rows[i].content != NULL )
                        {
                             free(aTable->rows[i].content);
                             aTable->rows[i].content = NULL;
                        }
                   }
                   free(aTable->rows);
                   aTable->rows = NULL;
              }
              free(aTable);
              aTable = NULL;
         }
         else
         {
              puts("*** avertissement: destroyTable(NULL)\n");
         }
    }

    Ce code te convient-il Emmanuel ? ou est-ce toujours bourré d'erreurs ?

    Bon développement à tous

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Mon projet de Table dynamique avance, mais devient trop grand pour afficher ici directement les sources. Je poste donc mon avancement dans les pièces jointes. Je les poste pour ceux qui souhaitent en profiter, sachant que les fonctionnalités ne sont pas encore complètes.
    Ceux qui veulent m'aider à améliorer ce système de table dynamique sont aussi les bienvenus, tout particulièrement pour la gestion de la mémoire.

    À noter que lorsque j'ai utilisé l'outil make pour la compilation, j'ai obtenu beaucoup d'erreurs, alors que dans mon EDI, je n'en ai pas, même en utilisant les mêmes CFLAGS. Je mets tout de même le makefile dans le paquet.
    Fichiers attachés Fichiers attachés

  11. #11
    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 Spootnik
    Ce code te convient-il Emmanuel ? ou est-ce toujours bourré d'erreurs ?
    Tant que tu n'as pas prouvé que tu savais allouer / désallouer un tableau à une dimension, c'est pas la peine d'écrire un allocateur avec un malloc() et un désallocateur avec des brouettes de free() imbriqués dans des boucles...

    Commence par le simple, après on verra.

    Mais le but n'est pas que "ça me convienne", mais que tu apprennes à écrire du code correct.
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Personnellement j'aime bien les brouettes de free, ça me rassure.

    Quant au fait que cela te plaise (ou pas), ce n'était pas vraiment le but de ma question. Simplement tu dis que ça ne va pas, mais tu ne dis pas pourquoi… et ça ne m'avance pas beaucoup. Je ne sais toujours pas ce qui d'après toi ne va pas.

    Je suis là pour apprendre. Certes il est plus aisé de commencer par des choses faciles, mais je préfère mettre la barre un peu plus haut pour commencer à faire des choses intéressantes. Pour info, ce que j'ai créé marche parfaitement chez moi, d'autant plus que ça affiche de très bonnes performances si je puis dire : 10 000 ajouts dans ma Table en quelques secondes. Et mon but est avant tout de créer quelquechose de performant, et surtout simple à utiliser pour ne pas faire d'erreur dans l'utilisation.

  13. #13
    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 Spootnik
    Simplement tu dis que ça ne va pas, mais tu ne dis pas pourquoi… et ça ne m'avance pas beaucoup. Je ne sais toujours pas ce qui d'après toi ne va pas.
    Bah, je t'ai proposé de t'aider, que puis-je faire de plus ? Oui, je considère qu'il faut y aller progressivement. Si tu veux bruler les étapes, ce sera sans moi.

    Par contre, si tu avances pas à pas, tes erreurs te sauterons aux yeux. C'est le but recherché.

    Si ça ne te plais pas, et que tu préfères qu'on fasse le boulot à ta place, ben, c'est ton problème...
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Je n'ai pas demandé à ce que les autres fassent le boulot à ma place (c'est d'ailleurs là qu'est toute la saveur de la programmation : réussir par soi-même, bien que je ne refuse pas l'aide).
    Je considère simplement que ce que j'ai créé jusqu'à maintenant (en partie grâce à DVP) montre bien que je ne suis pas complètement nul en programmation C. Je ne dis pas que je ne fais pas d'erreur ni que j'ai les bonnes habitudes, mais ce que j'ai créé fonctionne. Je rappelle que ça me fait 4 années de programmation déjà (même si certains diront que c'est peu). Et bien que j'aie surtout utilisé l'Objective-C jusqu'à maintenant, je cherche à apprendre ce que je considère comme les fondations d'un logiciel ou d'un OS : le C standard. Ce projet de table avait simplement pour but au départ de pouvoir créer des listes dynamiques d'objets.

    Après reflexion, je devrais peut-être suivre ton conseil : y aller progressivement. Mais là je ne vois pas vraiment l'intérêt, puisque ce que j'ai créé fonctionne, donc je ne vois pas l'utilité de faire plus simple si ce qui est compliqué fonctionne. Si au moins je savais pourquoi j'ai besoin de commencer par quelquechose de plus simple… Enfin tu me comprends non ?

  15. #15
    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 Spootnik
    Mais là je ne vois pas vraiment l'intérêt, puisque ce que j'ai créé fonctionne,
    Si tu es content de toi, qu'est-ce que tu viens demander ici ? J'avoue que j'ai du mal à suivre ...
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Je cherche à savoir ce qui, d'après un personne expérimentée comme toi, ne va pas dans mon code, puisque tu dis que rien ne va.

  17. #17
    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 Spootnik
    Je cherche à savoir ce qui, d'après un personne expérimentée comme toi, ne va pas dans mon code, puisque tu dis que rien ne va.
    OK. Je reprend ton code.
    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
     
    typedef struct{
    	unsigned int id;
    	char *content;
    } Row;
     
    typedef struct{
    	unsigned int count;
    	Row *rows;
    } Table;
     
    Table *newTable(void)
    {
         void *tmp = NULL;
         tmp = malloc(sizeof(Table));
     
         if (tmp != NULL)
         {
              Table *newTable = (Table *)tmp;
              newTable->count = 0;
              newTable->rows = NULL;
     
              return newTable;
         }
         else
         {
              return NULL;
         }
    }
    Or je ne vois qu'un seul malloc(), pas de boucles...

    Ca ressemble à une table vide.
    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
     
    void destroyTable(Table *aTable)
    {
         if (aTable != NULL)
         {
              if (aTable->rows != NULL)
              {
                   unsigned int i = 0;
                   unsigned int count = countOfItemInTable(aTable);
                   for(i = 0;i < count;i++)
                   {
                        if (aTable->rows[i].content != NULL )
                        {
                             free(aTable->rows[i].content);
                             aTable->rows[i].content = NULL;
                        }
                   }
                   free(aTable->rows);
                   aTable->rows = NULL;
              }
              free(aTable);
              aTable = NULL;
         }
         else
         {
              puts("*** avertissement: destroyTable(NULL)\n");
         }
    }
    OK, ça devrait marcher si on a la définition de countOfItemInTable().

    Ceci dit, la fonction Table *newTable(void) est extraordinairement compliquée. Pourquoi pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Table *newTable (void)
    {
       Table *p = malloc (sizeof *p);
     
       if (p != NULL)
       {
          p->count = 0;
          p->rows = NULL;
       }
       return p;
    }
    Est-ce que ça a vraiment besoin d'être plus compliqué que ça ?

    OK, à part ça, ça va.
    Pas de Wi-Fi à la maison : CPL

  18. #18
    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 Spootnik
    Mon projet de Table dynamique avance, mais devient trop grand pour afficher ici directement les sources. Je poste donc mon avancement dans les pièces jointes.
    Petit défaut : Dans countOfItemInTable(), c'est return 0; et non return NULL; qui n'a de sens que dans un contexte pointeur (ici, int).

    Autre chose. Evite les caractères exotiques. ASCII est portable (0-127) le reste, non.

    Le reste c'est OK. Je suis en train de le passer au détecteur de mensonges...

    http://emmanuel-delahaye.developpez.com/clib.htm
    Module SYSALLOC

    Ah, dommage...
    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
     
    Usage xxx[ /T][ /E][ /O][ <options application>]
    FRMWRK.DBG_SYSALLOC=1
    SYSALLOC Overload (85 rec)
    SYSALLOC Successful initialization: 85 records available
    Table myTable:
            n 1 : ben qu est-ce que j en sais moi ! ha ha :p
            n 2 : pour verifier qu on peut le modifier
    *** avertissement: destroyItem(): arg 1 invalide
     
    SYSALLOC min=4294967295 max=4294967295 delta=0
    SYSALLOC Err: Not-matched list:
    SYSALLOC Bloc 003D2558 freed at line 249 of 'table.c' not allocated
    SYSALLOC Bloc 003D25C0 freed at line 53 of 'table.c' not allocated
    SYSALLOC Bloc 003D24E0 freed at line 249 of 'table.c' not allocated
    SYSALLOC Bloc 003D2658 freed at line 53 of 'table.c' not allocated
    SYSALLOC Released Memory
    FRMWRK.Termine
     
    Press ENTER to continue.
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 216
    Points : 1 312
    Points
    1 312
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Or je ne vois qu'un seul malloc(), pas de boucles...
    C'est tout à fait normal, puisque je créé la table, mais pour l'instant la liste ne contient pas d'objet. Le tableau rows sera réalloué lors de l'ajout d'un objet dans la liste en fonction des objets déjà présents et de la taille du nouvel objet.

    Afin d'optimiser encore les perfomances, je vais stocker la taille actuelle que prennent tous les objets de la liste, pour ne pas avoir à recalculer cette taille à chaque fois que l'on utilise addRowToTable() (voir les fichiers sources).

    Citation Envoyé par Emmanuel Delahaye
    Ceci dit, la fonction Table *newTable(void) est extraordinairement compliquée.
    À noter que je tiens à créer un système de table qui me prévient lorsque quelquechose ne va pas, d'où tous les puts() ajoutés. À mon avis, ce que tu trouves compliqué, c'est plutôt le fait que je passe d'abord par un pointeur void * avant d'assigner l'adresse pour ma table. Je pensais que c'était une bonne habitude à prendre : je me suis basé sur la façon par laquelle tu alloues la mémoire dans le programme Indenteur :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    char *str_cat (char *str1, char const *str2)
    {
         /* ... */
         void *tmp = realloc (str1, len1 + strlen (str2) + 1);
     
         if (tmp != NULL)
         {
              strCat = tmp;
              /* ... */
         }
    }

    Bien que dans la table ce soit avec malloc(), le principe est le même.
    De plus, je tiens à prévenir l'utilisateur en cas d'erreur, et non pas simplement renvoyer un pointeur NULL. Cela pourrait donner quelquechose 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
     
    // creation de la Table
    Table *newTable(void)
    {
         // allocation de l espace necessaire
         Table *newTable = malloc(sizeof(Table));
     
         if (newTable != NULL)
         {
              // quelques mises au point une fois la memoire allouee
              newTable->count = 0;
              newTable->Items = NULL;
     
              return newTable;
         }
         else
         {
              puts("*** erreur: newTable(): memoire insuffisante\n");
              // retour NULL en cas de probleme lors de l allocation
              return NULL;
         }
    }

    Je ne trouve pas ce code compliqué.

    Citation Envoyé par Emmanuel Delahaye
    Petit défaut : Dans countOfItemInTable(), c'est return 0; et non return NULL; qui n'a de sens que dans un contexte pointeur (ici, int).
    NULL est défini par (en tout cas chez moi, mais je pense que c'est pareil chez tout le monde non ?) :
    Donc renvoyer NULL ou 0 revient au même (si les définitions sont les mêmes sur tous les systèmes). Je me trompe ?

    Citation Envoyé par Emmanuel Delahaye
    Autre chose. Evite les caractères exotiques. ASCII est portable (0-127) le reste, non.
    Tu parles des apostrophes et des quelques caractères accentués c'est ça ?

    Quant au erreurs de mémoire que tu as trouvées, je regarde ça dès que je suis chez moi .

    Merci pour ton aide

  20. #20
    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
    Spootnik a écrit :

    Donc renvoyer NULL ou 0 revient au même (si les définitions sont les mêmes sur tous les systèmes). Je me trompe ?
    Même si la définition de NULL est 0, NULL est reservé pour les pointeurs...

    Donc si c'est un int, il faut initialiser avec un int, et '0' est un int. Pas évident que NULL en soit un....
    "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

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 4 1234 DernièreDernière

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