[C99] Allouer un tableau de dimensions inconnues en une seule passe

Allouer un tableau de dimensions inconnues en une seule passe [C99] - C - Programmation

Marsh Posté le 25-08-2003 à 23:39:10    

Voilà, comme je vois souvent des débutants qui perdent là tête dès qu'ils voient une indirection double (ou plus) à allouer sur le heap (la version pile est beaucoup plus simple). je propose donc une méthode spécifique au C99 qui permet de s'affranchir des boucles for pleines de malloc à n'en plus finir.
 
Un exemple sur trois dimensions :

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(void) {
  4.     unsigned dim1;
  5.     unsigned dim2;
  6.     unsigned dim3;
  7.     puts("Entrez la taille des trois dimensions" );
  8.     scanf("%u%u%u", &dim1, &dim2, &dim3);
  9.     int (*tab)[dim2][dim3] = calloc(dim1 * dim2, dim3 * sizeof(int)); //allocation en une seule fois. ne pas enlever les parenthèses
  10.     //ici faites bon usage du tableau, comme si il avait été déclaré normalement "int tab[dim1][dim2][dim3]"
  11.     free(tab); //libération en une seule fois
  12.     return 0;
  13. }


 
Bien sur, il est possible de faire un realloc sur le tableau, mais il faudra bricoler un nouveau type à chaque fois que vous modifiez la taille des dimensions 2 et + (pas la première), ce qui signifie nouveau pointeur de tableau qui référence la zone mémoire... ou un typedef+cast. C'est donc à utiliser quand il n'y a pas trop de contraintes, car ça peut très vite devenir un code complètement illisible : à vous d'en faire bon usage !

Reply

Marsh Posté le 25-08-2003 à 23:39:10   

Reply

Marsh Posté le 25-08-2003 à 23:51:04    

j'ai mieux  
 

Code :
  1. #include <stdio.h>
  2. int main(int argc, char *argv[])
  3. {
  4.   unsigned dim1;
  5.   unsigned dim2;
  6.   unsigned dim3;
  7.    
  8.   puts("Entrez la taille des trois dimensions" );
  9.   scanf("%u%u%u", &dim1, &dim2, &dim3);
  10.    
  11.   int tab[dim1][dim2][dim3];
  12.   printf("sizeof tab = %u\n", sizeof tab);

 :p


Message édité par Taz le 25-08-2003 à 23:51:14
Reply

Marsh Posté le 25-08-2003 à 23:53:35    

Relis mon post.
Tu alloues sur la pile (alloca implicite), moi sur le heap tas (calloc explicite).


Message édité par leneuf22 le 26-08-2003 à 07:29:18
Reply

Marsh Posté le 25-08-2003 à 23:58:42    

bah je sais bien :heink:  
juste que mon code implique le tien


Message édité par Taz le 25-08-2003 à 23:58:49
Reply

Marsh Posté le 26-08-2003 à 00:03:14    

par contre, je ne suis pas d'accord aec les arguments du calloc,je préferais un générique
 
int (*dtab)[dim2][dim3] = calloc(dim1, sizeof *dtab);
 
ou alors
 
int (*dtab)[dim2][dim3] = calloc(dim1, sizeof(int[dim2][dim3]));
 
bien plus explicit


Message édité par Taz le 26-08-2003 à 07:29:37
Reply

Marsh Posté le 26-08-2003 à 00:05:10    

leneuf22 a écrit :

Relis mon post.
Tu alloues sur la pile (alloca implicite), moi sur le heap (calloc explicite).


 
Tu peux me citer le passage de la norme c99 qui dit que calloc alloue sur le heap ?

Reply

Marsh Posté le 26-08-2003 à 00:09:49    

tas !
 
 
non: aucune référence à la pile ou au tas
justement que le stockage par défaut est automatique
 
après malloc fait partie de la biliothèque standard, et il me semble que la seul chose dite est "retourne un pointeur vers une zone de la taille demandée"
 
tout dépend toujours de l'implémentation
 
 
edit: sous Gnu/Linux, en fonction du paramètres, soit cela conduit à un appel à sbrk pour faire grandir le segment, soit à un appel à mmap pour une projection


Message édité par Taz le 26-08-2003 à 00:10:51
Reply

Marsh Posté le 26-08-2003 à 11:44:56    

Citation :

The lifetime of an allocated object extends from the allocation until the deallocation. (until the space is explicitly deallocated)


 
Faut bien avouer que la pile n'est pas faite pour ce genre de comportement. Sinon faut plus l'appeler "pile", en tous cas elle n'est plus LIFO.

Reply

Sujets relatifs:

Leave a Replay

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