C++ では、Foo** foo;
ポインタへのポインタであり、配列の配列でもあると言われました。
なぜそれが配列の配列なのか、それともどのように解釈されるのかについて誰かが詳しく説明してくれますか?
実際には配列の配列ではありません。ただし、実際の 2D 配列と同じ構文で個々の要素にアクセスできます。
int x[5][7]; // A real 2D array
// Dynamically-allocated memory, accessed through pointer to pointer
// (remember that all of this needs to be deallocated with symmetric delete[] at some point)
int **y = new int*[5];
for (int i = 0; i < 7; i++) {
y[i] = new int[7];
}
// Both can be accessed with the same syntax
x[3][4] = 42;
y[3][4] = 42;
// But they're not identical. For example:
void my_function(int **p) { /* ... blah ... */ }
my_function(x); // Compiler error!
my_function(y); // Fine
他にも微妙なところがたくさんあります。より詳細な議論については、このトピックに関する C FAQ のすべてのセクションを読むことを強くお勧めします:配列とポインター(ほとんどすべてが C++ でも同様に有効です)。
ただし、C++ では、通常、このような生のポインターを使用する理由はほとんどありません。やなどstd::vector
のコンテナ クラスを使用すると、ほとんどのニーズをより適切に処理できます。std::array
boost::multi_array
配列の配列ではありませんFoo**
が、次の方法で配列の配列として構築できます。
Foo** arr = new Foo*[height];
for (int i = 0; i < height; ++i)
arr[i] = new Foo[width]; // in case of Foo has default constructor
個々の要素にアクセスするには、使用できます
arr[i][j].some_method();
また、タイプ のポインターへのポインターにすることもできますFoo
。
Foo* fooPointer = &fooInstance;
Foo** fooPointerPointer = &fooPointer;
これは配列の配列ではありません。ポインターは配列ではないため、ポインターへのポインターは配列への配列ではありません。
ただし、情報を格納および取得するために同様にインデックスを付けることができます...したがって、機能的には、配列と同じように機能します。
簡単な答え:C ++では、(可変サイズ、つまりint [5]のような固定サイズはありません)配列は、その配列の最初の要素へのポインターにすぎません。したがって、コンパイラーは、ポインターが配列の先頭を指しているのか、単一のインスタンスを指しているのかを区別できません。したがって、コンパイラーでは常にポインターを配列として扱うことができます。ただし、ポインタが配列として使用するのに十分な大きさのメモリブロックを指していない場合、それをそのまま使用すると、ある種のメモリ障害(セグメンテーション違反またはサイレント障害)が発生します。