Cの動的連続3Dアレイ
-
26-09-2019 - |
質問
私はCコードで動的に割り当てられた連続する3次元配列を実装しようとしています。私は配列のNetCDFファイル出力に頼ってるので、配列は連続している必要があります。今、私は解決策がここスタックオーバーフローソリューションを掲載適応しました。 NetCDFファイルは、それらを出力したときに動的配列を割り当て、それらのインデックスを作成するためのこの作品の罰金は...しかし、第二インデックスサイズ(jcount)とスケールに表示されるオフセットがあります。ここでは修正機能があります:
void*** newarray(int icount, int jcount, int kcount, int type_size)
{
int i,j,k;
void*** iret = (void***)malloc(icount*sizeof(void***)+icount*jcount*sizeof(void**)+icount*jcount*kcount*type_size);
void** jret = (void**)(iret+icount);
char* kret = (char*)(jret+icount*jcount);
for(i=0;i<icount;i++)
{
iret[i] = &jret[i*jcount];
}
for(i=0;i<icount;i++)
{
for(j=0;j<jcount;j++)
{
jret[i*jcount+j] = &kret[i*jcount*kcount*type_size+j*kcount*type_size];
}
}
return iret;
}
Iが正しくIRETは、IRET(最初のインデックス)を構成する3次元ポインタのためのスペースが割り当てられ、この機能を理解していれば、jret(第2指標)とkretを構成する実際の値のための空間を構成する2次元ポインタ。 2D jretポインタは、その後、IRETの2Dアレイ部と関連しています。そして、同じことがkretのために行われます。次いで、IRETのすべてのアドレスはjretの各セクションの第1の値に指摘されています。次いでjretの各アドレスはkretの最初のアドレスに指摘されている。
は記録のために、すべてが私のアレイ用のプリプロセッサ定義された値と罰金を働いていました。私は、彼らがすべて正しくインデックスに表示され、コードが正しく実行される配列の数値を確認するためのコードにいくつかのprintf文を使用する場合にも、それだけで、出力は配列の非連続的なメモリストレージの結果であると思われます。
私は、フォームの構造を持っています:
typedef struct
{
double ***test;
} STRUCT_TYPE;
私は、使用して割り当てる
mhd = (STRUCT_TYPE *) malloc(sizeof(STRUCT_TYPE));
mhd.test = (double***) newarray(101,7,101,sizeof(double));
これはNetCDFファイルで問題になる可能性があります...しかし、私はちょうど私のような割り当てルーチンは問題ではありません知っていると思います。
解決
これは実際にはレイザーの答えでは質問に対する答えです。
これは私は、それはそれが提供するポインタのためにメモリを割り当てる最初の値を格納するために>メモリが使用割り当てアレイのときC割り当てメモリだと思います 多次元配列の構造
たぶん誰かが私のために、この1をクリアすることができますか?
タグの間にCで非常に根本的な違いがあります
double arr[A][B][C];
と
double ***ptr;
両方がx[i][j][k]
で索引付けすることが可能であるが、は、得られたマシンコードは非常に異なっている。
double arr[A][B][C]
は、C倍のB列の配列の配列です。 arr[i][j][k]
ように、コードでこれをインデックス化すると、コンパイラは((i*B + j)*C + k)*sizeof(double)
のオフセットにそれを翻訳arr
の先頭からのバイト数。そこここに関与中間のポインタはありませんが、寸法BとCは、コンパイラに知られている必要があります。
「二重*** PTRは」へのポインタ(の配列の開始)へのポインタ(の配列の開始)へのポインタの二重(の配列の開始)です。 ptr[i][j][k]
ように、コードでこれをインデックス化すると、コンパイラは選択の余地がありませんが、個別に各インデックス操作を行うと、すべての中間指針に従うこと。
temp1 = ptr[i];
temp2 = temp1[j];
result = temp2[k];
メモリの単一のブロックの newarray
機能彫る、これらすべてのコンポーネントの配列アウトが、言語によって必要とされていないと、それはすべてのコンポーネントを処理するために持っているので、コンパイラは、これが起こっているという知識を持っていません互いに完全に独立したものとして-arrays。
他のヒント
さて、私は修正を見つけた...それはより多くの大会の事のだが。私はもともと私のコードを設計したとき、私は単に私の配列サイズを宣言するために、プリプロセッサディレクティブを使用していました。それから私は、単に構造内の各配列を宣言しました。メモリを節約するために私は単に私のサブ機能に構造体へのポインタを渡します。これは私が私のようなものを使用し、メイン()ルーチンの要素の外側を参照するつもりだったならば意味:
grid->x;
今、私は
のように、xの各要素を参照しますgrid->x[i][j][k];
netCDFの機能は、それが店に行っていた変数へのポインタを必要なときにもちろん、私はちょうど
それを渡されましたgrid->x
しかし、私は私が実際に様々なポインタ用に確保メモリ空間セットの最初のアドレスを渡している関数にこれを渡し、この新しいメモリ割り当て機能を使用して。本質的には、私は、メモリ内の誤ったアドレスへのポインタを渡しました。私がしなければならなかったすべてがに渡される引数を変更されます:
&grid->x[0][0][0]
と私は、適切な配列の出力を取得します。これは私はそれが最初にそれは多次元配列に構造を提供し、ポインタにメモリを割り当て値を格納するために使用されるメモリを割り当てアレイのときC割り当てメモリだと思います。
たぶん誰かが私のために、この1をクリアすることができますか?