0

重複の可能性:
C の柔軟な配列メンバー - 悪い?

次のコードを読みました。

struct hello {
    int number;
    int data[1];
};

柔軟な配列メンバーを使用すると、最後の要素を次のように宣言できることを知っていますarray of unspecified size

struct hello {
    int number;
    int data[];
};

このstructでは、最後の要素でサイズが指定されていませんが、これら 2 つの違いは何ですか? そして、最初の宣言は何を意味しますか?

4

4 に答える 4

1

この種の配列:

struct hello {
    int number;
    int data[];
};

構造体の最後の要素としてのみ意味があり、ヒープから構造体を割り当てる場合にのみ、通常はヘッダーフィールドに配列の実際のサイズが含まれるようにします。

struct hello *helloptr = malloc(sizeof (struct hello) + count*(sizeof int));
helloptr->number = count;

使用法は、ヘッダーとデータ バッファーを 1 つの構造体で便利に割り当てることです。

追加: サイズ 1 の配列を割り当てるバージョンとの違いは、sizeof struct hello未定義 = ゼロではなく 1 つの要素で配列が割り当てられるため、さらに大きくなります。これは、1 アイテム分のメモリを浪費するか、サイズの計算をより複雑にし、概念的には少し「醜い」ものです (実際には「未定義」を意味する場合、コードにはサイズ 1 の配列があり、場合によっては 0 でさえあります)。

OOP C++ では、動的に割り当てられたバッファーをクラス内でラップする方が適切です。これは、実際には一種の「ハック」です。

于 2012-11-29T09:45:08.950 に答える
0

最初の要素にしかアクセスしない場合でも、C では両方が完全に同等というわけではありません。柔軟な配列は、固定サイズの配列とは異なる配置にすることができます。したがってsizeof、両方で異なる結果が得られる可能性があるため、同じコード内でこれら 2 つのバリアントを混在させないでください。

于 2012-11-29T10:14:06.780 に答える
0

これは柔軟な配列メンバーではありませんが、古いコンパイラまたは C++ コンパイラで動作する必要がある一部のコードで使用されます。

これを柔軟な配列メンバーとして使用すると、未定義の動作が発生する可能性があります。実際のコードでは、このトリックはコンパイラが予期しないことを行うにはあまりにも多くのコードで使用されるため、これは期待どおりに機能するはずです。

于 2012-11-29T10:01:57.483 に答える
0

data[1]とはどう違いdata[0]ますか?

違いはありません。どちらも柔軟なサイズの構造を実装するために使用できます。

レイモンド・チェンはそれに適切に答えます

では、長さ 1 の配列の代わりに長さ 0 の配列を使用してみませんか?

タイムトラベルはまだ完成していないからです。

長さゼロの配列は、1999 年まで合法的な標準 C になりませんでした。Windows はそれよりずっと前に存在していたため、C 言語でその機能を利用することはできませんでした。

技術的には、2 番目のコード例はどちらも有効な C++ コードではないことに注意してください。[参照 1]しかし、既存のコードの多くはこの機能を使用しており、このコードはほぼ常に機能します。


[参照 1]参照:

C++11 標準: 8.3.4 配列

フォームを持つ宣言T DD

D1 [ constant-expressionopt] attribute-specifier-seqopt

....... 定数式 (5.19) が存在する場合、それは整数定数式であり、その値は 0 より大きくなければなりません

于 2012-11-29T09:47:36.617 に答える