Partage
  • Partager sur Facebook
  • Partager sur Twitter

tableau de structure dans un tableau de structure

et en plus je connais pas la taille des tableaux

    3 novembre 2006 à 11:08:41

    Bonjour,
    comme dit dans le titre, je souhaite inclure un tableau de structure (S_2 par exemple) dans un autre tableau de structure (S_1) le problème c'est qu'a la compilation je ne connais la taille d'aucun des tableau, en sachant que dans S_1[0].tableauDeS_2, le tableau pourra avoir un certain nombre d'élément et dans S_1[1].tableauDeS_2, le tableau pourra avoir un autre nombre d'élément.

    Je ne sais pas si mon explication est clair mais mon problème vient de l'allocation mémoire, en effet, j'ai une solution en tête mais celle ci contient des realloc (et encore j'ai pas testé) et je voudrais savoir si il n'y a pas une technique plus "simple/légère" (puisque je vois partout que realloc consomme beaucoup de ressources).

    PS: Je fait ça pour apprendre et j'aimerai autant ne pas avoir de solution toute faite mais surtout une méthode.

    merci d'avance
    • Partager sur Facebook
    • Partager sur Twitter
      3 novembre 2006 à 11:22:22

      Citation : Traouspont

      comme dit dans le titre, je souhaite inclure un tableau de structure (S_2 par exemple) dans un autre tableau de structure (S_1) le problème c'est qu'a la compilation je ne connais la taille d'aucun des tableau, en sachant que dans S_1[0].tableauDeS_2, le tableau pourra avoir un certain nombre d'élément et dans S_1[1].tableauDeS_2, le tableau pourra avoir un autre nombre d'élément.

      Je ne sais pas si mon explication est clair mais mon problème vient de l'allocation mémoire, en effet, j'ai une solution en tête mais celle ci contient des realloc (et encore j'ai pas testé) et je voudrais savoir si il n'y a pas une technique plus "simple/légère" (puisque je vois partout que realloc consomme beaucoup de ressources).

      PS: Je fait ça pour apprendre et j'aimerai autant ne pas avoir de solution toute faite mais surtout une méthode.

      merci d'avance


      La souplesse maximale consiste a utiliser des listes chainées. Eventuellement, des listes de listes si nécessaire. Voir aussi les arbres, mais c'est un peu plus complexe...

      Voilà un noeud 'magique' qui permet de construire n'importe quoi...

      enum node_type =
      {
         NT_DATA,
         NT_LIST,
         NT_etc
      };

      struct node
      {
         struct node *p_next;
         enum node_type type;
         void *p_data;
      };
      • Partager sur Facebook
      • Partager sur Twitter
      Music only !
        3 novembre 2006 à 11:39:15

        Citation : -ed-

        Voilà un noeud 'magique' qui permet de construire n'importe quoi...


        enum node_type =
        {
           NT_DATA,
           NT_LIST,
           NT_etc
        };

        struct node
        {
           struct node *p_next;
           enum node_type type;
           void *p_data;
        };

        TraouSpont <- note ça et garde ce morceau précieusement :-° ... ^^

        2 questions par contre là dessus:

        1- dans ta structure, le 2nd membre est de type enum (je ne savais pas qu'on pouvais utiliser un enum de cette façon) donc quelle est la différence avec un type int par exemple, si j'ai bien compris, le enum ne fait que remplacer des éléments quelconque par des valeurs ainsi dans ton cas (et avec ma façon de voir) NT_DATA = 0, NT_LIST=1, etc... si j'utilise un int c'est pareil non ? (c'est juste pour savoir)

        2- j'avais pensé au principe des listes chainées mais en fait, ce que je stock c'est une arborescence voir le sujet de départ et les listes chainées me paraissent moins simple pour accéder à un élément x ou y de mon arborescence.
        • Partager sur Facebook
        • Partager sur Twitter
          3 novembre 2006 à 11:48:14

          Citation : Pas de titre

          Citation : Traouspont


          1- dans ta structure, le 2nd membre est de type enum (je ne savais pas qu'on pouvais utiliser un enum de cette façon) donc quelle est la différence avec un type int par exemple,


          Aucune, si ce n'est que l'enum crée une abstraction qui fait qu'on a pas à se préoccuper de certains détails comme la valeur des constantes qui est attribuée automatiquement par le compilateur et dont, ici, on se fiche, du moment qu'elles sont différentes. Ce qui nous intéresse, par contre, c'est le sens (la sémantique) des constantes.

          2- j'avais pensé au principe des listes chainées mais en fait, ce que je stock c'est une arborescence voir le sujet de départ et les listes chainées me paraissent moins simple pour accéder à un élément x ou y de mon arborescence.


          souplesse et simplicité ne vont pas ensemble. Le compromis est le tableau souple (realloc()) que tu as déjà évoqué. C'est ce que j'utilise en général.

          http://mapage.noos.fr/emdel/clib.htm
          Modules FARR (Flexible ARRay) et FSTR (Flexible STRing)
          • Partager sur Facebook
          • Partager sur Twitter
          Music only !
            3 novembre 2006 à 13:34:18

            Ok, merci pour l'info, je vais donc coder ce que j'imaginais à savoir les realloc, mon tableau de struct concerné par le realloc est composé de peu de chose en plus, par structure j'ai:
            - 1 tableau de 25 char
            - 3 int
            - 4 pointeurs sur des int
            je pense donc qu'en faisant des realloc par paquet ça doit pas mettre les machines d'aujourd'hui à genou.
            (des paquets entre 2 et 5 par exemple mais je n'ai pas encore défini combien il me faut pour avoir quelque chose présentant un bon compromis, il faut que je test en charge)

            PS: j'aime bien la façon dont tu présentes tes fonctions dans tes .c, je pense que je vais plagier là :-° (je m'excuse par avance ^^ )
            • Partager sur Facebook
            • Partager sur Twitter
              3 novembre 2006 à 13:38:20

              Citation : Traouspont

              PS: j'aime bien la façon dont tu présentes tes fonctions dans tes .c, je pense que je vais plagier là :-° (je m'excuse par avance ^^ )


              J'en serais honoré.
              • Partager sur Facebook
              • Partager sur Twitter
              Music only !
                4 novembre 2006 à 13:03:24

                Bonjour,
                je suis en train de coder ce qu'on disait donc, mais j'ai un soucis au niveau de la réallocation de mon tableau de struct qui se trouve dans mon autre struct (et sans doute au niveau de mon allocation mais là ça plante pas donc jusque là je n'avais pas de doute)

                au début de mon prog, je commence par créer mon premier tableau de struct S_Principal en donnant une taille par défaut à ce tableau, donc en gros :
                *mesStructures =  malloc(STRUCT_SIZE_BY_DEF*sizeof(*mesStructures));
                (je suis dans une fonction que j'appelle en transmettant l'adresse de ma structure puisqu'elle vaut NULL au début, je lui transmet &mesStructures pour faire mon malloc d'où le "*")
                Ensuite, tant qu'à faire je me suis dit je vais tout de suite allouer la mémoire pour mon tableau de structure secondaire (S_Secondaire) (non non je ne raconte pas ma vie ^^ )
                je fait donc, dans cette même fonction:
                for (i=0;i<STRUCT_SIZE_BY_DEF;i++)
                {
                    (*mesStructures)[i].tableauStruct =
                                          malloc(TAB_SIZE_BY_DEF*sizeof((*mesStructures)[i].tableauStruct));                         
                }

                Et donc là soit je me trompe et je doit inclure cette taille dans l'allocation de ma structure principale (j'ai pas testé mais ça ne me paraissait pas logique, pour moi mesStructures[x].tableauStruct ne fait que contenir l'adresse de S_Secondaire pour x) soit c'est bien ça et je continue à raconter ma vie expliquer mon problème.
                Jusque là, aucun soucis apparent, je peux écrire et accéder ou je veux (je ne vous montre pas mais derrière ça j'initialise mes valeurs).

                Les choses se gâtent lorsque je veux reallouer une nouvelle taille à mon tableau de S_Principal (ou plutôt au nouveau tableau de S_Secondaire dans mes nouveaux éléments de mon tableau de S_Principal...si vous suivez toujours, le plus dur est passé :lol: )

                j'ai donc une fonction qui realloue la mémoire pour la nouvelle taille du premier tableau:
                S_Principal* p_tmp = realloc (mesStructures, newSizeStruct * sizeof(S_Principal));
                    if (p_tmp!=NULL)
                        mesStructures=p_tmp;

                et donc j'en profite là aussi (dans la même fonction) pour allouer de la mémoire à mes nouveaux tableaux de S_Secondaire:
                for (i=lastSizeStruct;i<newSizeStruct;i++)
                {
                    mesStructures[i].tableauStruct = malloc(TAB_SIZE_BY_DEF*sizeof(S_Secondaire));
                    if (mesStructures[i].tableauStruct == NULL)
                        memFail();
                }

                je n'alloue que la mémoire pour les nouveaux puisque selon moi, je ne touche pas aux autres (c'est sans doute là que je me trompe :euh: )
                A priori, l'allocation ne se passe pas trop mal puisque je n'appelle pas la fonction memFail() qui m'enverrai un message d'erreur le cas échéant.

                Sauf que là, si je peux accéder sans problème aux différents éléments de mes nouvelles S_Principal, il m'est impossible d'accéder à mes nouveaux tableaux de S_Secondaire...

                Donc ma question est la suivante, à quel moment mon raisonnement n'est pas bon ??? (j'espère que j'ai pas tous faux :o )

                Merci d'avance
                • Partager sur Facebook
                • Partager sur Twitter
                  4 novembre 2006 à 16:26:18

                  Citation : Traouspont

                  au début de mon prog, je commence par créer mon premier tableau de struct S_Principal en donnant une taille par défaut à ce tableau, donc en gros :

                  *mesStructures =  malloc(STRUCT_SIZE_BY_DEF*sizeof(*mesStructures));

                  (je suis dans une fonction que j'appelle en transmettant l'adresse de ma structure puisqu'elle vaut NULL au début, je lui transmet &mesStructures pour faire mon malloc d'où le "*")


                  Bug.
                  La forme canonique pour l'allocation d'un tableau de N éléments de type T est :
                  T *p = malloc (sizeof *p * N);

                  ou
                  T *p = malloc (N * sizeof *p);

                  c'est pareil.

                  Ce n'est pas ce que tu as écrit. Montre la fonction.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Music only !
                    4 novembre 2006 à 17:07:20

                    voici ma fonction pour créer le tableau mesStructures de taille STRUCT_SIZE_BY_DEF (taille de base donnée par un define), TAB_SIZE_BY_DEF est aussi un define sur la taille par défaut du tableau de struct S_Secondaire
                    void CreerStruct(S_Principal** mesStructures)
                    {
                        unsigned int i = 0;
                        *mesStructures = malloc(STRUCT_SIZE_BY_DEF*sizeof(*mesStructures));
                        if (*mesStructures == NULL)
                            memFail();
                        for (i=0;i<STRUCT_SIZE_BY_DEF;i++)
                        {
                            (*mesStructures)[i].tableauStruct =
                                                     malloc(TAB_SIZE_BY_DEF*sizeof((*mesStructures)[i].tableauStruct));
                            if ((*mesStructures)[i].tableauStruct == NULL)
                                memFail();
                        }
                    }


                    dans mon main,
                    S_Principal* mesStructures = NULL;
                    CreerStruct(&mesStructures);


                    edit: je pense que je viens de piger ma boulette :-° je vérifie ca de suite
                    • Partager sur Facebook
                    • Partager sur Twitter
                      4 novembre 2006 à 17:52:37

                      Citation : Traouspont

                      void CreerStruct(S_Principal** mesStructures)
                      {
                          unsigned int i = 0;
                          *mesStructures = malloc(STRUCT_SIZE_BY_DEF*sizeof(*mesStructures));



                      edit: je pense que je viens de piger ma boulette :-° je vérifie ca de suite


                      Voui. Tu as créé un tableau de pointeurs au lieu d'un tableau de structure. Il faut suivre les règles canoniques que j'ai rappelées au-dessus.

                      Je conseille une interface de type malloc() ou fopen(), c'est à dire qui retourne l'adresse du bloc. C'est beaucoup plus simple... et ça corrige ton bug instantanément...


                      dans ton main,
                      S_Principal* mesStructures = CreerStruct();


                      D'autre part, il est absurde d'utiliser malloc() pour créer des données de taille fixe. Les constantes de tailles doivent rester à leur place, c'est à dire au niveau applicatif. Dans la fonction (qui peut être ailleurs, voire en bibliothèque, donc ne rien savoir de l'application), on doit rester souple et travailler avec des paramètres.
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Music only !
                        4 novembre 2006 à 18:20:27

                        Citation : -ed-

                        D'autre part, il est absurde d'utiliser malloc() pour créer des données de taille fixe. Les constantes de tailles doivent rester à leur place, c'est à dire au niveau applicatif. Dans la fonction (qui peut être ailleurs, voire en bibliothèque, donc ne rien savoir de l'application), on doit rester souple et travailler avec des paramètres.



                        Oui mais dans mon cas, je crée mes tableaux avec malloc car à ma connaissance, je ne peux pas utiliser realloc derrière si je les crée de cette façon ?
                        S_Principal mesStructures[5]


                        Pour le reste, c'est bon, ton premier post m'a fait comprendre de suite mon erreur, j'ai recodé de cette façon et ça fonctionne (ça plante pas en tout cas...):
                        --Dans le Main--

                            S_Principal* mesStructures = CreerStruct();
                        ...après changement du nombre de struct S_Principal...
                            newSizeStruct = 10;
                            mesStructures = ReallocStruct (mesStructures,&lastSizeStruct,newSizeStruct);

                        --Les deux fonctions en question--

                        // Creation du tableau de structure principal au lancement
                        S_Principal* CreerStruct()
                        {
                            unsigned int i = 0;
                            S_Principal* mesStructures = malloc(STRUCT_SIZE_BY_DEF*sizeof(*mesStructures));
                            if (mesStructures == NULL)
                                memFail();
                            for (i=0;i<STRUCT_SIZE_BY_DEF;i++)
                            {
                                mesStructures[i].tableauStruct =
                                                         malloc(TAB_SIZE_BY_DEF*sizeof(mesStructures[i].tableauStruct));
                                if (mesStructures[i].tableauStruct == NULL)
                                    memFail();
                            }
                            return mesStructures;
                        }
                        // Reallocation du tableau de structure principal en fonctionnement
                        S_Principal* ReallocStruct (S_Principal* mesStructures,size_t* lastSizeStruct,size_t newSizeStruct)
                        {
                            unsigned int i=0;
                            S_Principal* p_tmp = realloc (mesStructures, newSizeStruct * sizeof(S_Principal));
                            if (p_tmp!=NULL)
                                mesStructures=p_tmp;
                            for (i=(*lastSizeStruct);i<newSizeStruct;i++)
                            {
                                mesStructures[i].tableauStruct = malloc(TAB_SIZE_BY_DEF*sizeof(S_Secondaire));
                                if (mesStructures[i].tableauStruct == NULL)
                                    memFail();
                            }
                            return mesStructures;
                        }


                        PS: ce que je montre, c'est mon bac à sable, ça peu expliquer que l'intéret paraisse limité au vu des arguments que je passe et des valeurs par défaut de certain.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          4 novembre 2006 à 18:39:07

                          Citation : Traouspont

                          Citation : -ed-

                          D'autre part, il est absurde d'utiliser malloc() pour créer des données de taille fixe. Les constantes de tailles doivent rester à leur place, c'est à dire au niveau applicatif. Dans la fonction (qui peut être ailleurs, voire en bibliothèque, donc ne rien savoir de l'application), on doit rester souple et travailler avec des paramètres.



                          Oui mais dans mon cas, je crée mes tableaux avec malloc car à ma connaissance, je ne peux pas utiliser realloc derrière si je les crée de cette façon ?

                          S_Principal mesStructures[5]



                          Je ne conteste pas l'utilisation de malloc() en tant que tel, mais le fait que la fonction utilise des dépendances externes applicatives (constantes) ce qui est une Mauvaise Pratique. Je veux des paramètres.

                          D'ailleurs, dans le code applicatif qui suit, on voit un 10 tomber du ciel... Pas bon du tout. C'est à l'application de gérer ma taille ou alors il faut que ce soit automatique. Mais il faut plus que l'adresse d'un tableau...

                          http://mapage.noos.fr/emdel/clib.htm
                          Module FARR

                          mais là, on est d'avantage dans une optique industrielle...
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Music only !
                            4 novembre 2006 à 22:00:31

                            Citation : -ed-

                            Je ne conteste pas l'utilisation de malloc() en tant que tel, mais le fait que la fonction utilise des dépendances externes applicatives (constantes) ce qui est une Mauvaise Pratique. Je veux des paramètres.

                            D'ailleurs, dans le code applicatif qui suit, on voit un 10 tomber du ciel... Pas bon du tout. C'est à l'application de gérer ma taille ou alors il faut que ce soit automatique. Mais il faut plus que l'adresse d'un tableau...

                            http://mapage.noos.fr/emdel/clib.htm
                            Module FARR

                            mais là, on est d'avantage dans une optique industrielle...


                            d'où mon PS qui peu t'expliquer pourquoi j'ai des chiffres magique qui apparaissent, ceci est mon bac à sable (ma zone de test, d'entrainement) j'utilise beaucoup cela pour faire tous mes tests ce qui me permet de faire abstraction de tous le reste du code, je ne suis qu'un petit zéro qui a encore besoin de beaucoup tester ces idées pour voir si elles sont réalisable/cohérente, ensuite, je fait des test sur quelque chose de plus approchant de la solution utilisé et après seulement j'intègre au code ^^ (qui a dit trop prudent ? :lol: )
                            dans cette exemple et pour info, ceci va rentrer dans une appli avec une GUI (gtk) mais avant cela, je vais déjà l'intégrer dans un code en console qui est presque fini (bon d'accord l'interface gtk est déjà faite elle aussi mais pour l'instant elle est mise de coté. Elle est pas joli joli et j'ai pas réussi à installer la libglade correctement :( )
                            • Partager sur Facebook
                            • Partager sur Twitter

                            tableau de structure dans un tableau de structure

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown