Carte mémoire pour un tableau 2D en C
Pensez-vous que cette discussion sur la mémoire-carte de tableau 2D est correcte? Surtout cette photo? Pouvez-vous expliquer la théorie?
Supposons que nous déclarons un tableau 2D en C comme ceci:
int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90};
Maintenant, d'après cette discussion, la mémoire sera organisée comme suit:
Maintenant, j'ai écrit le code suivant pour tester cette théorie:
#include <stdio.h>
main()
{
int arr[3][3]={10, 20, 30, 40, 50, 60, 70, 80, 90};
printf(" arr==%d\n", arr);
printf(" &arr[0]==%d\n", &arr[0]);
printf(" arr[0]==%d\n", arr[0]);
printf("&arr[0][0]=%d\n", &arr[0][0]);
printf(" arr[0][0]=%d\n", arr[0][0]);
}
/*
Output:
========
arr ==1245028
&arr[0] ==1245028
arr[0] ==1245028
&arr[0][0]==1245028
arr[0][0]==10
Press any key to continue...
*/
Pourquoi les 4 premières sorties sont les mêmes?
source d'informationauteur anonymous
Vous devez vous connecter pour publier un commentaire.
Votre code utilise juste un simple tableau multidimensionnel, mais l'image décrit un tableau de pointeurs, comme le genre, vous faites lorsque malloc-ing choses.
Un tableau multidimensionnel est fondamentalement juste un normal, aplaties, array (de mémoire) avec un certain syntatic sucre pour y accéder. Ainsi, alors qu'il est possible d'obtenir un pointeur de arr[i], il n'y a pas une "variable" juste pour stocker ce, qui se passe dans votre image.
Pour corriger l'image, supprimer les parties avec le
arr[0], arr[1]...
et modifier la valeur dearr
à1245039
(le même que &arr[0][0]).Voir ma question ici.
Qui n'est pas la façon dont vous accédez à de l'information sur les tableaux 2d. En fait, vous pouvez juste penser à eux comme 1-d, où vous multipliez et ajouter les indices d'une manière spéciale.
par exemple
Ce sont formaté exactement la même dans la mémoire, et ils ressemblent à ceci:
De sorte à obtenir le
8
élément, vous pouvez demander l'x[8]
ouy[1][3]
.Pour la deuxième façon, vous pouvez la considérer comme
(1 * 5) + 3
.C'est pourquoi vos 4 premiers étaient les mêmes. Vous avez:
arr
: c'est l'adresse de début du tableauarr[0]
: c'est l'adresse du début de la première sous-tableau, ce qui est la même que pour le départ de l'ensemble de la matrice de&arr[0][0]
: c'est l'adresse du premier élément du premier sous-ensemble, aussi le départ de l'ensemble de la matrice dearr[0][0]
: c'est la valeur stockée dans le premier élément de la première sous-tableau.Les quatre premiers produits sont les même raison de l'obtention de l'adresse du premier élément du tableau, c'est à dire &arr[0][0]. La dernière sortie est de son contenu.
bien, autant que je me souvienne, en C++ (et je pense que C, bien que ce n'est pas mon fort) d'un tableau 2d déclaré que
Values[][]
est généralement (je ne sais pas si toujours) mis en œuvre comme un tableau de style C tableaux. toutefois, lorsque vous les déclarez sur la pile (par exemple, une variable locale), je crois que la mémoire mise en forme est différente.ainsi, lorsque vous déclarez une variable locale tout est posé comme si c'était juste un tableau 1d, et vous obtenez des choses de prévu, de sorte que vous pouvez exprimés pour un pointeur, puis accéder à un tableau 1D.(!) cependant, il est toujours reconnu de la même manière comme un tableau 2D dans le champ d'application de la déclaration, et éventuellement si vous passez à un paramètre qui est déclarée avec la
[]
notation.mais, si vous attribuez l'un de ces sur le tas (par exemple, globales ou statiques ou via de nouvelles), l'histoire est différente. maintenant, la mémoire est aménagé comme un véritable tableau de tableaux, et de sorte que les résultats réels de la mémoire des lieux vous index si vous lancez un tableau 1D et l'index est maintenant pointeurs au lieu.
j'ai vérifié mon souvenir, en procédant de la manière suivante: j'ai créé
int HeapArray[3][3];
mondial, etint StackArray[3][3];
local (à la fois avec les initialiseurs de{ { 10, 20, 30 }, {40, 50, 60}, {70, 80, 90 } }
). à l'intérieur de ma fonction, j'ai choisi les deux d'entre eux à un pointeur de int,int* ptrHeapArray = (int*)HeapArray;
etint* ptrStackArray = (int*)StackArray;
et puis regarda la valeur de retour de la 0e élément de chaque.[edit: oups, j'ai inversé; fixe]
ptrStackArray[0]
était égale à 10ptrHeapArray[0]
était égal à un pointeur sur un int[3];donc je pense que mon peu de rappel précis. 🙂 espérons que cette aide!