1

C99 プログラムを作成しようとしていますが、暗黙的に次のように定義された文字列の配列があります。

char *stuff[] = {"hello","pie","deadbeef"};

配列の次元が定義されていないため、各文字列に割り当てられるメモリの量は? すべての文字列に、定義内の最大の文字列と同じ量の要素が割り当てられていますか? たとえば、次のコードは上記の暗黙の定義と同等になります。

char stuff[3][9];
strcpy(stuff[0], "hello");
strcpy(stuff[1], "pie");
strcpy(stuff[2], "deadbeef");

それとも、各文字列には、定義時に必要な量のメモリが割り当てられていますか (つまりstuff[0]6 つの要素stuff[1]の配列を保持し、4 つの要素の配列を保持し、 9 つstuff[2]の要素の配列を保持します)?

4

4 に答える 4

12

写真が役に立ちます — ASCII Art は楽しいです (しかし面倒です)。

char *stuff[] = {"hello","pie","deadbeef"};

+----------+          +---------+
| stuff[0] |--------->| hello\0 |
+----------+          +---------+      +-------+
| stuff[1] |-------------------------->| pie\0 |
+----------+          +------------+   +-------+
| stuff[2] |--------->| deadbeef\0 |
+----------+          +------------+

ポインターの 1D 配列に割り当てられたメモリは連続していますが、配列に保持されているポインターがメモリの連続したセクションを指しているという保証はありません (これが、ポインター行の長さが異なる理由です)。

char stuff[3][9];
strcpy(stuff[0], "hello");
strcpy(stuff[1], "pie");
strcpy(stuff[2], "deadbeef");

+---+---+---+---+---+---+---+---+---+
| h | e | l | l | o | \0| x | x | x |
+---+---+---+---+---+---+---+---+---+
| p | i | e | \0| x | x | x | x | x |
+---+---+---+---+---+---+---+---+---+
| d | e | a | d | b | e | e | f | \0|
+---+---+---+---+---+---+---+---+---+

2D 配列に割り当てられるメモリは連続しています。x は、初期化されていないバイトを示します。stuff[0]は 'hello' の 'h' へのポインタであり、はstuff[1]'pie' の 'p' へのstuff[2]ポインタであり、'deadbeef' の最初の 'd' へのポインタです (またstuff[3]、逆参照不可能なポインタです) 'deadbeef' の後の null バイトを超えるバイトまで)。

写真はかなり、かなり異なります。

次のいずれかを記述できることに注意してください。

char stuff[3][9] = { "hello", "pie", "deadbeef" };
char stuff[][9]  = { "hello", "pie", "deadbeef" };

また、2D 配列図に示されているのと同じメモリ レイアウトになります (ただし、x はゼロになります)。

于 2012-12-12T23:54:33.657 に答える
4
char *stuff[] = {"hello","pie","deadbeef"};

多次元配列ではありません!これは単にポインタの配列です。

各文字列にどのくらいのメモリが割り当てられていますか?

文字数とヌルターミネータ。他の文字列リテラルと同じです。

私はあなたがこれを望んでいると思います:

char foo[][10] = {"hello","pie","deadbeef"};

ここで、10は文字列あたりのスペースの量であり、すべての文字列は連続したメモリにあります。したがって、サイズ10未満の文字列にはパディングがあります。

于 2012-12-12T23:43:14.180 に答える
2

最初の例では、それは私が推測するジャグ配列です。

これは、charへのconstポインタの配列を宣言します。したがって、文字列リテラルは好きなだけ長くすることができます。文字列の長さは、配列の列に依存しません。

2番目の例では、1行あたりの文字数(string)の長さは、列サイズで指定されている9以下である必要があります。

于 2012-12-12T23:41:46.877 に答える
0

すべての文字列には、定義内の最大の文字列と同じ量の要素が割り当てられていますか?

いいえ、割り当てられるポインタは3つだけで、3つの文字列リテラルを指します。

char *stuff[] = {"hello","pie","deadbeef"};

char stuff[3][9];

まったく同等ではありません。1つ目は3つのポインターの配列で、2つ目は2D配列です。

最初のポインタのみが割り当てられ、それらが指す文字列リテラルは読み取り専用セクションに格納される場合があります。2つ目は、自動ストレージ(通常はスタック)に割り当てられます。

于 2012-12-12T23:42:43.147 に答える