int myArray [10] [20]などの配列を作成すると、保証された連続したメモリブロックがスタックから割り当てられ、通常の配列演算を使用して配列内の任意の要素が検索されます。
その3D「配列」をヒープから割り当てたい場合は、malloc()を使用してメモリを取り戻します。その記憶は「ばかげている」。これは単なるメモリのチャンクであり、ベクトルと見なす必要があります。配列に付随するナビゲーションロジックには付属していません。つまり、目的の3D配列をナビゲートする別の方法を見つける必要があります。
malloc()を呼び出すとポインターが返されるため、最初に必要な変数は、実際の整数データIEを保持する必要があるint*のベクトルを保持するためのポインターです。
int * pArray;
...しかし、これはまだ整数を格納したいストレージではありません。あなたが持っているのは、現在何も指していないポインタの配列です。データのストレージを取得するには、malloc()を10回呼び出す必要があります。各malloc()は、呼び出しごとに20個の整数にスペースを割り当て、その戻りポインターはポインターの*pArrayベクトルに格納されます。この意味は
int * pArray
に変更する必要があります
int ** pArray
ポインタのベクトルのベースへのポインタであることを正しく示すため。
最初の間接参照*pArray[i]は、intポインターの配列内のどこかに到達し、2番目の間接参照* p [i] [j]は、intポインターの配列内のどこかに到達します。 pArray[i]。
IE:ヒープ全体に散在する整数ベクトルのクラウドがあり、それらの位置を追跡するポインターの配列によって示されます。スタックから静的に割り当てられたArray[10][20]とはまったく異なります。これはすべて連続したストレージであり、どこにも単一のポインターがありません。
他の人が理解していなかったように、ポインタベースのヒープメソッドは一見したところあまり効果がないように見えますが、非常に優れていることがわかります。
まず第一に、free()またはrealloc()を使用して、いつでもヒープメモリのサイズを変更でき、関数が戻ったときにスコープ外になることはありません。さらに重要なことに、経験豊富なCコーダーは、可能な場合はベクトルを操作するように関数を配置します。この場合、関数呼び出しで1レベルの間接参照が削除されます。最後に、使用可能なメモリに比べて大きなアレイの場合、特に大規模な共有マシンでは、連続したメモリの大きなチャンクは使用できないことが多く、動作にメモリを必要とする他のプログラムには適していません。スタックに割り当てられた大きな静的配列を持つコードは、メンテナンスの悪夢です。
ここで、テーブルは、ベクトル操作から返されたベクトルポインターを収集するシェルであり、興味深いことはすべてベクトルレベルまたは要素レベルで発生することがわかります。この特定のケースでは、VecRand()のベクトルコードはcalloc()自身のストレージを呼び出し、calloc()のリターンポインタをTblRand()に返しますが、TblRandにはVecRand()のストレージを割り当てる柔軟性もあります。 VecRand()へのNULL引数を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;
}