Allocation Mémoire pour tableau 2 dimensions

Allocation Mémoire pour tableau 2 dimensions - C - Programmation

Marsh Posté le 22-11-2015 à 19:16:17    

Bonjour,  
Quelqu'un pourrait m'aider.
je souhaite initier un tableau de type
          double** abondances_s_tab [nb_sp] [100];
etat.nb_sp se situant dans une structure est une variable non fixe. je veux donc faire une allocation de mémoire dynamique pour la première dimension.
J'ai essayé de faire quelque chose comme ça mais rien de concluant.
 

Code :
  1. double** abondances_s_tab;
  2. abondances_s_tab=(int **)malloc(etat.nb_sp,sizeof(int));
  3. for(i=0;i<etat.nb_sp;i++)
  4.       j=100;


 
 
Quelqu'un peut m'aider ?
 
Merci d'avance.
Bien cordialement.
Axelle DURAND
 

Reply

Marsh Posté le 22-11-2015 à 19:16:17   

Reply

Marsh Posté le 23-11-2015 à 11:51:23    

La méthode plus pédagogique mais moins optimale (101 appels à malloc) est la suivante:

Code :
  1. double** abondances_s_tab;    // utilisé comme double abondances_s_tab [nb_sp] [100];  
  2. abondances_s_tab = (double **) malloc(nb_sp * sizeof(double*));
  3. for (i = 0; i < nb_sp; ++i) {
  4.     abondances_s_tab[i] = (double *) malloc(100 * sizeof(double));
  5. }
  6. // a ce stade, on peut employer abondances_s_tab comme un tableau


La méthode la plus optimale (2 appels à malloc seulement) est la suivante:

Code :
  1. double** abondances_s_tab;    // utilisé comme double abondances_s_tab [nb_sp] [100];  
  2. abondances_s_tab = (double **) malloc(nb_sp * sizeof(double*));
  3. abondances_s_tab[0] = (double *) malloc(nb_sp * 100 * sizeof(double));
  4. for (i = 0; i < nb_sp; ++i) {
  5.     abondances_s_tab[i] = (*abondances_s_tab + (100 * i));
  6. }
  7. // a ce stade, on peut employer abondances_s_tab comme un tableau

Noter aussi qu'avec cette dernière méthode, tous les doubles sont rangés dans une zone contiguë en mémoire, comme ce serait le cas si on avait un vrai tableau.
Dans les deux cas, on alloue nb_sp * (sizeof(double*) + 100 * sizeof(double)) octets. On alloue donc nb_sp * sizeof(double*) octets de plus (ie la première allocation) que pour un vrai tableau.
 
A+,


Message édité par gilou le 23-11-2015 à 15:00:16

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 23-11-2015 à 17:07:23    

Encore merci Gilou.
Axelle

Reply

Marsh Posté le 23-11-2015 à 18:48:31    

Note qu'on peut faire encore mieux, en passant tout à une fonction, et avec une seule allocation:
 

Code :
  1. // dans une fonction c'est mieux, surtout qu'on retourne un pointeur, ce qui est optimal
  2. double** double_dynamicArray2D(int x, int y) {
  3.   double** array = (double **) malloc((x * sizeof(double*)) + (x*y * sizeof(double)));
  4.   if (array) {
  5.       int i;
  6.       for (i = 0; i < x; ++i) {
  7.         array[i] = (double*)(array + x) + i * y;
  8.       }
  9.   }
  10.   return array;
  11. }
  12. // Et on fait dans son code
  13. double** abondances_s_tab = double_dynamicArray2D(nb_sp, 100);
  14. ...
  15. free(abondances_s_tab);


La fonction fait une allocation unique (on colle les pointeurs en premier et les données derrière), et le gros avantage, c'est qu'un unique free suffit à libérer la mémoire.
 
On peut généraliser, mais ça devient vite complexe:

Code :
  1. double*** double_dynamicArray3D(const int x, const int y, const int z) {
  2.   double*** array = (double ***) malloc((x * sizeof(double**)) + (x*y * sizeof(double*)) + (x*y*z * sizeof(double)));
  3.   if (array) {
  4.       int i, j;
  5.       for (i = 0; i < x; ++i) {
  6.         array[i] = (double**)(array + x) + i * y;
  7.         for (j = 0; j < y; ++j) {
  8.           array[i][j] = (double*)(array + x + x*y) + i * y*z + j * z;
  9.         }
  10.       }
  11.   }
  12.   return array;
  13. }


 
A+,


Message édité par gilou le 23-11-2015 à 18:55:56

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed