union
Linux環境でCを理解して使用しようとしています。私が次の組合を持っているとしましょう
union test {
int one;
long two;
} t1;
t1.one
ネットワークファイル記述子(ソケットfd)に書き込む場合、ユニオンが最大の要素である2つを選択すると、余分なゼロがfdに書き込まれます。構造の結合によってさらに悪化する可能性があります。誰かがこれを克服する方法を教えてもらえますか?
union
Linux環境でCを理解して使用しようとしています。私が次の組合を持っているとしましょう
union test {
int one;
long two;
} t1;
t1.one
ネットワークファイル記述子(ソケットfd)に書き込む場合、ユニオンが最大の要素である2つを選択すると、余分なゼロがfdに書き込まれます。構造の結合によってさらに悪化する可能性があります。誰かがこれを克服する方法を教えてもらえますか?
Anは、構造のようではなくunion
、最大の要素(この場合)のサイズを持っています。long
変更one
すると、longの最初の32ビット(32ビットOS 16の場合)が上書きされます。変更two
すると、スペース全体が上書きされone
て失われます。
union test
64ビットOSの場合:- 64 bit +
│ union test │
├──────────────────┤
│ long │
├─────────┬────────┘
│ int |
└─────────┘
struct test
64ビットOSの場合:- 96 bit +
│ struct test │
├──────────────────┬─────────┤
│ long │ int │
└──────────────────┴─────────┘
test.oneをネットワークfdに書き込む場合、余分なゼロがfdに書き込まれます。
余分なバイトが書き込まれることは正しいですが、これらのバイトの内容は必ずしもすべてゼロになるとは限りません。未定義です。一般に、他のフィールドを介して一部のデータを書き込んだ領域を超えているユニオンに属するバイトを読み取ることは、未定義の動作です。書き込まれるデータの量を制御する場合は、書き出す特定のタイプを指定する必要があります。
いいえ、test.one
ネットワークfdに書き込む場合は、正確にsizeof (int)
バイトを書き込みます。 オブジェクトですtest.one
。int
組合全体にアクセスしない限り、それがたまたま組合のメンバーであるという事実は関係ありません。
ユニオン全体を作成する場合は、もちろん、ユニオンのフルサイズを作成します。これは、少なくとも最大メンバーのサイズになります。
だからそうしないでください。
ユニオンのどのメンバーが現在であるか(つまり、最後に値を割り当てたメンバー)を追跡し、そのメンバーだけを使用します。
繰り返しになりますが、あなたが私たちに提供した最小限の情報を考えると、ユニオンを使用することがまったく意味があるかどうかは明らかではありません。