Partage
  • Partager sur Facebook
  • Partager sur Twitter

Allocation dynamique d'un tableau 2d

    19 mars 2017 à 1:19:32

    Bonsoir, après avoir effectuer regarder sur google les différents moyen de faire un tableau 2d en allocation dynamique. Je n'est rien trouvé de clair. 

    J'aimerai donc savoir si quelqu'un pourrais m'expliquer clairement comment faire un tableau 2d dynamique ?

    Et me montrer comment l'envoyer à une fonction pour cette fonction modifie l'état des valeurs du tableau 

    Merci 

    • Partager sur Facebook
    • Partager sur Twitter
      19 mars 2017 à 9:10:49

      GUIGUI59_ a écrit:

      Bonsoir, après avoir effectuer regarder sur google les différents moyen de faire un tableau 2d en allocation dynamique. Je n'est rien trouvé de clair. 

      Es-tu sûr d'avoir bien cherché? Cette question est posée toutes les semaines!

      Si les 2 dimensions sont dynamiques, on utilise un pointeur de pointeurs.

      // Allocation
        float** tab2D = malloc( NbLignes * sizeof*tab2D );
        for ( int i = 0 ; i < NbLignes ; ++i )
            tab2D[i] = malloc( NbColonnes * sizeof**tab2D );
      
      // Utilisation
        tab2D[ligne][colonne] = 1.1;
      
      // Libération
        for ( int i = 0 ; i < NbLignes ; ++i )
            free( tab2D[i] );
        free( tab2D );
      
      // Passage en paramètre (par référence -> la fonction peut modifier le tableau)
      // c'est même plus simple que pour tout autre type de données
      void fct( float** tab ) {
          tab2D[ligne][colonne] = 1.1;
      }
      • Partager sur Facebook
      • Partager sur Twitter

      En recherche d'emploi.

        19 mars 2017 à 11:37:58

        Sinon, le plus simple est de linéarité le tableau.

        Un tableau avec n lignes, p colones peut être créer avec un tableau de n*p cases. et tu accèdes à la case (i,j) en faisant tab[i*p + j ]

        float* tab2D = malloc( NbLignes *NbColonnes * sizeof(float) );
        
        tab2D[ligne + NbColonnes*colonne] = 1.1;
         

         Il me semble d'ailleurs que c'est la solution la plus optimisé niveau utilisation de mémoire, mais je ne suis pas sur .

        -
        Edité par edouard22 19 mars 2017 à 11:41:34

        • Partager sur Facebook
        • Partager sur Twitter
          19 mars 2017 à 12:05:05

          GUIGUI59_ a écrit:

          Bonsoir, après avoir effectuer regarder sur google les différents moyen de faire un tableau 2d en allocation dynamique. Je n'est rien trouvé de clair. 

          J'aimerai donc savoir si quelqu'un pourrais m'expliquer clairement comment faire un tableau 2d dynamique ?

          Et me montrer comment l'envoyer à une fonction pour cette fonction modifie l'état des valeurs du tableau 

          Merci 


          Bonjour,

          tu n'as rien trouvé de clair ; donc je suppose qu'en gros tu n'as pas compris ce que tu as trouvé ?

          Il y a plusieurs solutions à cette demande, mais avant tout il faut bien comprendre qu'en C il n'existe pas de moyen de faire un tableau multidimensionnel car un tableau en C n'a qu'une et qu'une seule dimension.
          On peut néanmoins s'en sortir en utilisant des tableaux de tableaux en considérant par exemple qu'un tableau de L lignes et C colonne est en fait un tableau de longueur L, chaque case étant un tableau de longueur C .Dalfab utilise cette vision des choses en utilisant des pointeurs.
          On peut aussi considérer que ce tableau est linéarisé et le voir comme un grand tableau de longueur L×C. Pour accéder à un élément il faut faire un petit calcul pas très compliqué. C'est en fait ce que C fait avec les tableaux de tableaux. C'est la solution proposée Edouard22.
          Il y a encore deux autres approches. Une approche hybride qui mélange les deux dernières. On alloue une grande zone mémoire et des pointeurs vers le début de chaque ligne, et, enfin, l'utilisation d'un pointeur sur un tableau. Il y a des avantages et des inconvénients à chaque approche.

          Mais le plus important est aussi de ne pas oublier que dans la majorité des cas il va falloir se trimbaler les dimensions et là il va falloir tout encapsuler dans uns tructure pour ne pas commencer à construire une usine à gaz. Et tout dépend de ce que tu veux faire.

          • Partager sur Facebook
          • Partager sur Twitter
          First solve the problem. Then, write the code. ~ John Johnson
            19 mars 2017 à 12:47:22

            edouard22 a écrit:

            Il me semble d'ailleurs que c'est la solution la plus optimisé niveau utilisation de mémoire, mais je ne suis pas sur .

            C'est en effet plus optimum en taille et quasi-systématiquement optimum en temps d'accès par rapport à la méthode que j'ai proposé.
            L'utilisation de pointeurs intermédiaires peut quand même accélérer les cas :
            * Le nombre de colonnes nécessite une 'vraie' multiplication ; multiplier par 31 est généralement plus lent que faire une indirection.
            * Le nombre de colonnes est grand ; la probabilité d'avoir des fautes de page dans le cache est impactée, en mieux ou en moins bien suivant la manière d'accéder au tableau.

            En digressant un peu, pour les tableau 2D de taille statique, la linéarisation est plus rarement optimale car le compilateur justement utilisera en interne la linéarisation quand il la trouvera optimale.

            int tabL[3*255];  // linearisation
            int tab[3][255];  // laisser agir le compilateur
              // le compilateur va peut-être allouer [5*256] pour optimiser les multiplications
              // le compilateur sur un DSP pourra faire un accès directement en 2D à la mémoire (avec une contrainte d'alignement)
            
            • Partager sur Facebook
            • Partager sur Twitter

            En recherche d'emploi.

              19 mars 2017 à 13:09:07

              Dalfab a écrit:

              edouard22 a écrit:

              Il me semble d'ailleurs que c'est la solution la plus optimisé niveau utilisation de mémoire, mais je ne suis pas sur .

              C'est en effet plus optimum en taille et quasi-systématiquement optimum en temps d'accès par rapport à la méthode que j'ai proposé.

              Tout dépend de ce que l'on veut représenter. Dans le  cas de matrices creuses ni l'une ni l'autre n'est optimale en terme d'occupation mémoire. Les méthodes dans le cas général qui consomment le moins de mémoire sont effectivement celles qui nécessitent le moins de pointeurs.

              Dalfab a écrit:

              L'utilisation de pointeurs intermédiaires peut quand même accélérer les cas :

              * Le nombre de colonnes nécessite une 'vraie' multiplication ; multiplier par 31 est généralement plus lent que faire une indirection.
              * Le nombre de colonnes est grand ; la probabilité d'avoir des fautes de page dans le cache est impactée, en mieux ou en moins bien suivant la manière d'accéder au tableau.

              La méthode la plus cache friendly est celle qui maximise la localité des données, donc la méthode du tableau linéarisé ou du pointeur de tableau ; pas celle des pointeurs de pointeurs (sauf en version hybride).

              Dalfab a écrit:

              En digressant un peu, pour les tableau 2D de taille statique, la linéarisation est plus rarement optimale car le compilateur justement utilisera en interne la linéarisation quand il la trouvera optimale.

              int tabL[3*255];  // linearisation
              int tab[3][255];  // laisser agir le compilateur
                // le compilateur va peut-être allouer [5*256] pour optimiser les multiplications
                // le compilateur sur un DSP pourra faire un accès directement en 2D à la mémoire (avec une contrainte d'alignement)
              
              Attention, en C standard un tableau est forcément une zone mémoire contigüe. Dans ton exemple tab sera obligatoirement (au minimum) une zone mémoire contigüe de 3*255*sizeof(int) bytes (3 zones contigües de 255 zones contigües de la taille d'un int). L'alignement et la taille «effectivement occupée» sont indépendante de ce fait.
              • Partager sur Facebook
              • Partager sur Twitter
              First solve the problem. Then, write the code. ~ John Johnson
                19 mars 2017 à 22:14:46

                Merci beaucoup pour tout vaut réponse.

                J'ai chercher mais j'avais pas compris mais la je pense avoir compris.

                Je vais essayer dans les jours a venir de faire comme vous m'avez dit.

                Merci

                • Partager sur Facebook
                • Partager sur Twitter
                  28 mars 2017 à 22:50:47

                  Bon sa marcher mais la quand je programme sa marche une fois sur 8 environ et le problème semble apparaitre lors des free()

                  Voici mon code:

                  int conversionHexDec(char chaineCaractere[]);
                  int nombreDeTriangle();
                  int main()
                  {
                      float* coordonnePoint = NULL;
                      float* coordonneMIN = NULL;
                      float* coordonneMAX = NULL;
                  
                      float hauteurMin=0, hauteurMAX=0;
                  
                      int nb2Triangle=10;
                  
                      nb2Triangle=nombreDeTriangle();
                      printf("%d\n",nb2Triangle);
                  
                      coordonnePoint=malloc(nb2Triangle*3*3*sizeof(float));  // coordonnePoint[nb2Triangle][axe][facet]
                      coordonneMIN=malloc(nb2Triangle*3*sizeof(float));
                      coordonneMAX=malloc(nb2Triangle*3*sizeof(float));
                  
                      if(coordonnePoint!=NULL)
                      {
                          if(coordonneMIN!=NULL)
                          {
                              if(coordonneMAX!=NULL)
                              {
                                  lireCoordonne(coordonnePoint,nb2Triangle);
                                  definitionMin(coordonnePoint,coordonneMIN,coordonneMAX,nb2Triangle);
                              }
                              else
                              {
                                  printf("Probleme allocation dynamique coordonneMAX\n");
                              }
                          }
                          else
                          {
                               printf("Probleme allocation dynamique coordonneMIN\n");
                          }
                      }
                      else
                      {
                           printf("Probleme allocation dynamique coordonnePoint\n");
                      }
                  
                      free(coordonnePoint);
                      free(coordonneMIN);
                      free(coordonneMAX);
                  
                      return 0;
                  }
                  void definitionMin(float *coordonnePoint,float *coordonneMin,float *coordonneMax,int nbTriangle)
                  {
                      float minimum=0,maximum=0;
                      int axe,numFacet,numTriangle;
                  
                      for(numTriangle=0;numTriangle<nbTriangle;numTriangle++)// plus petit ou egal ?
                      {
                          for(axe=0;axe<3;axe++)
                          {
                              minimum=MaxFlOAT;
                              maximum=MinFLOAT;
                              for(numFacet=0;numFacet<3;numFacet++)
                              {
                                  if(coordonnePoint[(numTriangle*9)+((numFacet+1)*3)+axe]<minimum)
                                  {
                                      minimum=coordonnePoint[(numTriangle*9)+((numFacet+1)*3)+axe];
                                  }
                                  if(coordonnePoint[(numTriangle*9)+((numFacet+1)*3)+axe]>maximum)
                                  {
                                      maximum=coordonnePoint[(numTriangle*9)+((numFacet+1)*3)+axe];
                                  }
                              }
                  
                              coordonneMin[(numTriangle*3)+axe]=minimum;
                              coordonneMax[(numTriangle*3)+axe]=maximum;
                              printf("CoordonneMin[%d][%d]=%f\n",numTriangle,axe,coordonneMin[(numTriangle*3)+axe]);
                              printf("CoordonneMax[%d][%d]=%f\n",numTriangle,axe,coordonneMax[(numTriangle*3)+axe]);
                  
                          }
                      }
                  }



                  • Partager sur Facebook
                  • Partager sur Twitter

                  Allocation dynamique d'un tableau 2d

                  × 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