1

C99 標準では、次のような柔軟な配列メンバーを作成できます。

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;

これは、次のようなもので初期化されますpstring* s = malloc(sizeof(pstring) + len)lenをゼロにすることは許されますか? それは一貫しているように見え、時々スペースを節約するのに適しています(pstringもちろん、おそらく例ではありません)。一方、次のコードが何をするのかわかりません。

pstring* s = malloc(sizeof(pstring));
s->string;

これはまた、あるコンパイラーでは動作するが別のコンパイラーでは動作しない、またはある OS では動作し、別の OS では動作しない、またはある日と別の OS では動作しないようなものであるように思われるので、私が本当に知りたいのは、標準がこれについて何を述べているかです。それmallocはサンプルコードの未定義の動作s->stringですか、それとも無効なアクセスのみですか、それともまったく別のものですか?

4

2 に答える 2

7

行うことは有効ですが、s-> string [0]にアクセスしたり、データにアクセスする関数にs->stringをフィードしたりすることは無効です。

C99標準は実際に(§6.7.2.1)と言っています:

struct s { int n; double d[]; };

..。

struct s t1 = { 0 }; // valid

..。

への割り当てt1.d[0]はおそらく未定義の動作ですが、

sizeof (struct s) >= offsetof(struct s, d) + sizeof (double)

その場合、割り当ては正当になります。それにもかかわらず、厳密に準拠したコードでは表示できません。

于 2011-02-18T05:05:41.653 に答える
1

かつて、Microsoft C では次のことが許可されていました。

struct pstring {
  size_t length;
  char string[0];
};

そして、このようなものを使用してテキストエディターを構築しました。ただし、これはずっと前のことであり、当時は非標準であったことはわかっています。私は、Microsoft がまだそれをサポートしていると 100% 確信しているわけではありません。

肝心なのは、コンパイラと現在のコンパイル設定に依存するということです。

于 2011-02-18T04:52:04.787 に答える