0

次のコードを検討してください。

static char a[2][2] = {
    { 1, 2 },
    { 3, 4 },
};

int main()
{
    char **p = (char**)a; // needs cast, or compiler complains (which makes sense)

    printf("%p\n", p);

    printf("%p\n", &a[1][0]);
    printf("%d\n",  a[1][0]);
    printf("%p\n", &p[1][0]); // why null?  why doesn't compiler complain about this?
    printf("%d\n",  p[1][0]); // segfault, of course

    return 0;
}

これにより、次の出力が得られます。

0x804a018
0x804a01a
3
(nil)
Segmentation fault

配列がポインターに減衰する可能性があることを理解しています。私が理解していないのは、なぜコンパイラ (g++) が逆のことを試みさせてくれるのかということです。p が char** の場合、警告なしで p[x][x] を使用できるのはなぜですか? 結果のポインターがnullであるため、明らかに機能することさえありません。

ちなみに、私は明らかに彼らのために働くサードパーティからのコードについてこれを求めています。(g++ ではなく Windows でコンパイル)。したがって、このコードを修正する方法についての提案を探しているわけではありません。その方法は既に知っています。コンパイラが文句を言わない理由と、結果が null ポインターである理由を理解したいだけです。

ありがとう。

4

3 に答える 3

0

あなたがこれを言うとき:

char a[2][2];
char **p = (char**)a;

それは間違いです。 a文字へのポインターの配列ではありません。これは、それぞれが文字の配列であるストレージ ブロックの配列です。

于 2013-02-22T19:07:15.813 に答える