Vue d’ensemble de la mémoire des baies multidimensionnelles

Dernièrement, j’ai commencé à apprendre les pointeurs et les références en c ++ (pas seulement leur utilisation habituelle, mais toutes sortes de façons, je ne veux pas avoir de problèmes avec eux dans un proche avenir).

De mon sharepoint vue, un tableau alloué statique 1d est similaire à un pointeur int * const. Mon problème est que, lorsque j’alloue dynamicment avec un pointeur, le pointeur lui-même a une adresse mémoire autre que le premier élément, ce qui n’est pas le cas dans un tableau 1d. Ceci est un exemple

int a[5]; cout<<&a<<" "<<&a[0]<<"\n"; int* t=new int[10]; cout<<&t<<" "<<&t[0]<<"\n"; 

La sortie est:

 0x6afed0 0x6afed0 0x6afecc 0xcb0e40 

Je ne peux pas penser à la façon dont le tableau 1d est stocké. Vous pouvez stocker une valeur ou une adresse à 1 bloc de 4 octets. J’ai essayé aussi avec les tableaux 2D, et il y a plus d’intersections.

 q = new int*[10]; for (i=0;i<10;i++) q[i] = new int[i+1]; cout<<&q<<" "<<&q[0]<<" "<<&q[0][0]<<"\n"; int b[10][10]; cout<<&b<<" "<<&b[0]<<" "<<&b[0][0]<<"\n"; 

Sortie:

 0x6afee4 0xe40e40 0xe41240 0x6afd54 0x6afd54 0x6afd54 

Si quelqu’un m’éclairait et m’expliquait comment ces tableaux étaient stockés, je vous en serais reconnaissant.

EDIT: Pour être plus précis, je sais et il est logique que le tableau créé dynamicment avec le nouveau mot clé par le pointeur soit stocké. Mais comment & a et & a [0] ont les mêmes valeurs, si a doit stocker l’adresse d’un [0] .Ce bloc de mémoire (& a) stocke quoi alors? La valeur d’un [0] ou l’adresse d’un [0 ]. J’espère que j’ai été clair dans quel est mon problème.

Un tableau est un object qui contient un bloc contigu de N objects, où N est une taille constante. L’adresse du tableau est le début du tableau, donc l’adresse du premier object et les adresses du tableau sont identiques.

Un pointeur sur un tableau est un object unique. Puisqu’il s’agit de son propre object, il possède sa propre adresse, distincte de celle qu’il détient. donc avec int* t=new int[10]; &t est l’adresse de t&t[0] est l’adresse du premier élément du tableau qui a été alloué par new.

Les tableaux sont des entités de première classe du langage. Ainsi, lorsque vous déclarez une variable de tableau

 int a[10]; 

le compilateur connaît les dimensions du tableau. Lorsque vous allouez un espace de stockage dynamic

 int* p = new int[10]; 

Seuls vous et l’allocateur connaissez la taille de cet espace.

Dans la version tableau, a est le tableau. Il a une adresse, mais cette adresse est conservée par le compilateur lors de la compilation. Dans le paramètre d’allocation, p est l’adresse des données, qui ne seront pas connues avant l’exécution.

Ce qui cause la confusion chez les gens, c’est que, dans l’ensemble, les deux semblent interchangeables: vous pouvez faire un calcul de pointeur et de calcul mathématique avec les deux, utilisez l’un ou l’autre des points où un pointeur est attendu:

 void f(int*); int a1 = a[1]; f(a); int p1 = p[1]; f(p); 

Ceci est voulu, c’est quelque chose qui s’appelle tableau-pointeur-équivalence .

Une grande partie de la confusion entourant les tableaux et les pointeurs en C peut être atsortingbuée à une incompréhension de cette déclaration. Dire que les tableaux et les pointeurs sont «équivalents» ne signifie ni qu’ils sont identiques ni même interchangeables. Cela signifie que l’arithmétique des tableaux et des pointeurs est définie de manière à ce qu’un pointeur puisse être utilisé de manière pratique pour accéder à un tableau ou pour simuler un tableau. En d’autres termes, comme l’a dit Wayne Throop, il s’agit de “” l’arithmétique de pointeur et l’indexation de tableau [qui] sont équivalentes en C, les pointeurs et les tableaux sont différents. “ )

Plus précisément, la pierre angular de l’équivalence est cette définition clé:

Une référence à un object de type array-of-T qui apparaît dans une expression se décompose (à trois exceptions près) en un pointeur sur son premier élément; le type du pointeur résultant est un pointeur sur T.

t est un pointeur déclaré sur la stack qui contient l’adresse d’un tableau sur le tas. &t obtient l’adresse de t , AKA l’emplacement de t sur la stack. Si vous voulez accéder au premier membre du tableau, vous pouvez soit faire *t ou t[0] . C ++ supprime automatiquement les références et effectue l’arithmétique de pointeur en fonction du type de t lorsque vous utilisez la notation entre crochets.

Cependant, &t[0] vous fournit essentiellement l’adresse de t[0] , c’est pourquoi il est différent de &t , car &t habite sur la stack tandis que &t[0] vit sur le tas. Donc si vous voulez l’adresse de t[0] , vous pouvez utiliser cette notation, sinon restz sur t[0] si vous voulez juste les valeurs.

&t prend l’adresse du pointeur t , pas l’adresse du premier élément. L’adresse du premier élément est juste t (car t est un int* , qui pointe vers le bloc de mémoire).