重複の可能性:
ポインターを介して2次元配列を渡す
int table[20][20];
int** table1 = table;
int a;
table[0][0] = 4;
a = table1[0][0];
最後の行は私にアクセス違反を与えます、そして私はそれを取得しません..
前もって感謝します!
重複の可能性:
ポインターを介して2次元配列を渡す
int table[20][20];
int** table1 = table;
int a;
table[0][0] = 4;
a = table1[0][0];
最後の行は私にアクセス違反を与えます、そして私はそれを取得しません..
前もって感謝します!
簡単な答えは、ポインタへのポインタは配列の配列と同じではないということです。
1つの割り当てで2次元のint配列からint**を作成することはできません。まず、正しい数のポインターを割り当てる必要があります。table1 = malloc(sizeof(int *)* 20);
次に、ループを使用して次のレベルのポインターを入力できます。
for(int i = 0; i < 20; i++)
table1[i] = table[i];
その理由は、ポインタへのポインタがアドレスを保持する1つのメモリ位置であるためです。最初の割り当てを行うと、そのポインターは20個のintポインターを指すようになります。次に、これらの各ポインタに、元のテーブルの各行の最初のアドレスを割り当てます。ここで、を使用するa = table1[0][0]
と、コンパイラはtable1 [0]をフェッチします。つまり、ループ内に設定した配列の最初のポインタです。これはtable[0]行を指しているので、そこから[0]要素をフェッチし、そこに詰め込まれた4を取得します[もちろん、他の数値インデックスも4を取得するため、機能することを示すのは困難です。この場合は正しい)。
このtable[y][x]
場合、コンパイラはテーブルのアドレスを取得し、それにy * 20 * sizeof(int)を追加してから、x * sizeof(int)を追加します。これは、「テーブル」がそうである「正方形」の記憶の塊の中で私たちに素晴らしい場所を与えてくれます。
(繰り返しますが、入力しすぎて、これを書き始めてからさらに2つの答えがあります)
Cコンパイラは寛容すぎます:
int** table1 = table;
cc:関数'main'内:cc:3:17:警告:互換性のないポインタ型からの初期化[デフォルトで有効]
間違ったコードをフィードすると、コンパイラーが文句を言い、その文句を無視して奇妙な結果が得られた場合、疑問に思う必要がありますか?
とにかく、table1はintへのポインターを指しておらず、クラッシュする方法は実装の問題です(アライメント、セグメンテーションなど)。
は table1[1]
ポインタ型ですが、のどこにもポインタはありませんtable
。
与えられた
int table[20][20];
table
と互換性がありますがint*
、ではありませんint**
。
table1
これはコンパイルされ、からtable1[0]
にアクセスできるはずtable1[399]
です:
int* table1 = table;
自問してみてください。ポインタが与えられ、項目3、4にアクセスするように指示された場合、適切な量の項目をスキップするために、コンパイラは2次元配列の最初の次元の大きさをどのように知る必要がありますか?
正解:まったくありません。