Bonjour à tous,
Je travaille avec de gros tableaux. Comme il m'arrive fréquemment d'être un peu limite question mémoire, je souhaite pouvoir créer des tableaux dans le stack.
Enfin, c'est ce que j'ai compris, mais je n'en suis pas certain ; il semble qu'il y a deux sortes de mémoires. Si l'on crée un tableau avec des dimensions connues à la compilation par
par exemple, on utilise une sorte de mémoire. Si au contraire on crée le tableau à l'exécution par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 char table[1000000][2]
on utilise alors une autre sorte de mémoire, qui est moins limitée que la première, et surtout qui en tous cas vient en complément de la première. Il me semble que c'est celle-là que l'on appelle le "stack". L'autre avantage est bien entendu d'avoir la possibilité d'ignorer les dimensions du tableau à la compilation : on peut utiliser une variable pour dimensionner à l'exécution.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 char **table_dyn; ... table_dyn = new char*[dim1]; for (int j=0;j<dim1;j++) table_dyn[j] = new char[dim2];
Mais peut-être n'ai-je rien compris ! Suis-je complètement à côté de la plaque ?
Je connais dès la compilation les dimensions de mes tableaux, donc cette possibilité de les dimensionner à l'exécution seulement ne m'est pas indispensable.
Ma question concerne la mémoire occupée, d'une part, les performances du programme, d'autre part.
Avec :
l'occupation mémoire est exactement de 2000000 octets (logique !). sizeof(table) me renvoie bien 2000000. Et la différence d'adresse entre le dernier octet et le premier octet de mon tableau est bien 1999999.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 char table[1000000][2]
Ce qui me gêne c'est que dans le cas d'une définition dynamique avec "new",
je constate que les deux octets table_dyn[0][0] et table_dyn[0][1] étant bien dans deux adresses consécutives, l'octet suivant (table_dyn[1][0]) est situé après un saut de 14 octets. De même, les octets table_dyn[1][0] et table_dyn[1][1] sont consécutifs, et table_dyn[2][0] saute à nouveau 14 octets. Et ainsi de suite (je pense que C++ utilise systématiquement une adresse multiple de 16 à chaque utilisation de "new"). Il me semble clair qu'à chaque utilisation de "new" le système place le nouveau tableau là où il trouve de la place, ce qui ne me gêne nullement) mais surtout, qu'il perd systématiquement des octets (ici, 14) à vouloir placer les nouveau tableaux à des adresses multiples de 16 (et ça, ça ma gêne car cela multiplie par 8 (dans mon cas) la place occupée).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 char **table_dyn; ... table_dyn = new char*[dim1]; for (int j=0;j<dim1;j++) table_dyn[j] = new char[dim2];
sizeof(table_dyn) me donne 4 !! Bah, cela ça m'est égal, mais bon !
Le deuxième problème est qu'avec une telle organisation, les performances du programme risquent fort d'être dégradées à cause d'une double référence mémoire pour localiser chaque élément du tableau - ceci étant dû à la non régularité des emplacements.
Mes questions est donc :
Y-a-t-il moyen de créer un tableau à deux dimensions en une seule commande avec new, de manière à créer un bloc de 2000000 octets consécutifs sans gaspillage de mémoire et en optimisant les performances ?
Et :
Y-a-t-il moyen de créer un tableau de dimensions connues à la compilation, mais dans cette deuxième mémoire utilisée par "new" (c'est-à-dire dans le "stack, n'est-ce pas ?), possibilité qui elle aussi résoudrait mon problème ?
Merci d'avance pour vos réponses !
Partager