Lors de la création d'un tableau, tel que int monTableau [10] [20], est affecté un bloc contigu garanti de mémoire à partir de la pile, et normale L'arithmétique de tableau est utilisée pour trouver n'importe quel élément dans le tableau.
Si vous souhaitez allouer ce "tableau" 3D à partir du tas, vous utilisez malloc() et récupérez de la mémoire. Ce souvenir est "stupide". C'est juste un morceau de mémoire, qui devrait être considéré comme un vecteur. Aucun élément de la logique de navigation associé à un tableau ne vient avec cela, ce qui signifie que vous devez trouver un autre moyen de naviguer dans le tableau 3D souhaité.
Depuis votre appel à malloc() renvoie un pointeur, la première variable dont vous avez besoin est un pointeur pour tenir le vecteur de int * s que vous allez avoir besoin de tenir certaines données entier réel IE:
int * pArray;
... mais ce n'est toujours pas le stockage que vous souhaitez stocker les entiers. Ce que vous avez est un tableau de pointeurs, pointant actuellement vers rien. Pour obtenir le stockage de vos données, vous devez appeler malloc() 10 fois, chaque malloc() allouant de l'espace pour 20 entiers sur chaque appel, dont les pointeurs de retour seront stockés dans le vecteur * pArray des pointeurs. Cela signifie que
int * parray
doit être changé pour
int ** parray
pour indiquer à juste titre qu'il est un pointeur sur la base d'un vecteur de pointeurs. Le premier déréférencement, * pArray [i], vous place quelque part dans un tableau de pointeurs int, et le 2ème déréférencement, * p [i] [j], vous place quelque part dans un tableau d'ints, pointé par un pointeur int dans pArray [i].
IE: vous avez un nuage de vecteurs entiers dispersés sur tout le tas, pointé par un tableau de pointeurs gardant la trace de leurs emplacements. Pas du tout similaire à Array [10] [20] alloué statiquement à partir de la pile, qui est tout le stockage contigu, et n'a pas un seul pointeur dans n'importe où.
Comme d'autres ont échappé à, la méthode de tas de pointeur ne semble pas avoir beaucoup de choses à faire à première vue, mais s'avère être massivement supérieure. Tout d'abord, vous pouvez free() ou realloc() pour redimensionner la mémoire de tas quand vous voulez, et il ne sort pas de la portée lorsque la fonction retourne. Plus important encore, les codeurs C expérimentés organisent leurs fonctions pour fonctionner sur des vecteurs lorsque cela est possible, où 1 niveau d'indirection est supprimé dans l'appel de fonction. Enfin, pour les grands tableaux, par rapport à la mémoire disponible, et en particulier sur les grandes machines partagées, les gros morceaux de mémoire contiguës sont souvent indisponibles et ne sont pas compatibles avec d'autres programmes nécessitant de la mémoire. Les codes avec de grands tableaux statiques, alloués sur la pile, sont des cauchemars de maintenance.
Ici, vous pouvez voir que la table est juste une coquille rassemblant des pointeurs vectoriels retournés par des opérations vectorielles, où tout intéressant se produit au niveau du vecteur, ou au niveau de l'élément. Dans ce cas particulier, le code vectoriel dans VecRand() est calloc() en mémoire propre et renvoyant le pointeur de retour de calloc() à TblRand(), mais TblRand a la possibilité d'allouer aussi le stockage de VecRand(), simplement en remplaçant l'argument NULL à VecRand() avec un appel à calloc()
/*-------------------------------------------------------------------------------------*/
dbl **TblRand(dbl **TblPtr, int rows, int cols)
{
int i=0;
if (NULL == TblPtr){
if (NULL == (TblPtr=(dbl **)calloc(rows, sizeof(dbl*))))
printf("\nCalloc for pointer array in TblRand failed");
}
for (; i!=rows; i++){
TblPtr[i] = VecRand(NULL, cols);
}
return TblPtr;
}
/*-------------------------------------------------------------------------------------*/
dbl *VecRand(dbl *VecPtr, int cols)
{
if (NULL == VecPtr){
if (NULL == (VecPtr=(dbl *)calloc(cols, sizeof(dbl))))
printf("\nCalloc for random number vector in VecRand failed");
}
Randx = GenRand(VecPtr, cols, Randx);
return VecPtr;
}
/*--------------------------------------------------------------------------------------*/
static long GenRand(dbl *VecPtr, int cols, long RandSeed)
{
dbl r=0, Denom=2147483647.0;
while (cols--)
{
RandSeed= (314159269 * RandSeed) & 0x7FFFFFFF;
r = sqrt(-2.0 * log((dbl)(RandSeed/Denom)));
RandSeed= (314159269 * RandSeed) & 0x7FFFFFFF;
*VecPtr = r * sin(TWOPI * (dbl)(RandSeed/Denom));
VecPtr++;
}
return RandSeed;
}
'bla [5]' 'à bla [999]' sont des bornes extérieures. Pourquoi y accédez-vous dans 'fillArray'? –
Je suis assez sûr que le pointeur vers la déclaration de pointeur est également faux. –
Pas faux, juste redondant – StoryTeller