8

次のコードの2番目のオプションを初期化しようとするとnames、セグメンテーション違反が発生します。2番目のオプションには概念的に間違っていることがあると思います。何か案は?

 char *names[] = {
            "Alan", "Frank",
            "Mary", "John", "Lisa"
        };

 char **names = {
            "Alan", "Frank",
            "Mary", "John", "Lisa"
        };
4

4 に答える 4

6

はい。最初のケースでは、ポインターの配列があります。各ポインタは個別のアイテムを指します(Alan、Frank ...)

2番目の宣言

char **names;

名前がポインタへのポインタであることを意味します[このような文字列のセットを初期化することはできません]。のように

char *str = "hello"
char **names = &str;
于 2012-06-06T11:32:06.467 に答える
2

それは完全に異なるメモリレイアウトを持っています。

最初の例は、ポインターの配列です。の5倍のサイズを占めchar *ます。

ただし、2番目の例は、1つ以上char *が予想される場所へのポインターです。あなたがそれをするようにそれを初期化することは不可能です。

于 2012-06-06T11:32:40.340 に答える
2

最初のケースでは、の配列がありchar*ます。これは、5つのchar *変数(配列のエントリ)にメモリを割り当て、次々とメモリにきちんと配置されていることを意味します。また、それぞれが各文字列の先頭に初期化されます。

2番目のケースでは、char**タイプのポインターが1つあります。1つのポインタに十分なメモリしかありません。

(各文字列に割り当てられたメモリの説明はスキップしました。どちらの場合も同じである可能性がありますが、ここでは関係ありません)

于 2012-06-06T11:42:43.940 に答える
0

gccでセグメンテーション違反が発生することはありません。ただし、整数配列でこれを同じように試みると、それがあまり意味をなさない理由を説明できる可能性があります。

char* names[] = { "Dennis", "Richie" };
char** more_names = { "Sarah", "O'connor" };

printf("Name: %s %s\n", names[0], names[1] );
printf("Name: %s %s\n", more_names + 0, more_names + 1);

int numbers[] = { 0, 1 };
int x = 2, y = 3;
int* more_numbers = { &x, &y };

printf("Numbers: %d, %d\n", numbers[0], numbers[1] );
printf("Numbers: %d, %d\n", *(more_numbers + 0), *(more_numbers + 1));

奇妙なことに、この例では実際に整数配列に対して期待される結果が生成されます。ただし、gccは警告を生成します。

于 2012-06-06T12:01:18.300 に答える