4

原則として同じサイズにする必要がある2つの異なるデータ構造体がありますが、なぜそうしないのか疑問に思っています。

struct pix1 { 
    unsigned char r; 
    unsigned char g;
    unsigned char b; 
    unsigned char a; 
    unsigned char y[2]; 
 }; 

struct pix2 { 
    unsigned char r; 
    unsigned char g;
    unsigned char b; 
    unsigned char a; 
    unsigned short y; 
 }; 

次に、これらのピクセルの 4 つをグループ化します。

struct pix4 {
    pix1 pixels[4]; // or pix2 pixels[4]
    unsigned char mask;
};

...しかし、pix1 と pix2 のどちらを使用するかによって、sizeof(pix4) に従って、このようなグループ化のサイズが変化することがわかりました。個々の sizeof(pix1) == sizeof(pix2) であるため、ピクセルのカルテットをグループ化するとサイズが変わる理由について混乱しています。2 つの unsigned char を使用するよりも short を使用した方がプログラムを作成しやすいので気になりますが、1 ピクセルあたり 0.25 バイトのコストがかかります。

他のタイプのマシンでテストしていないため、このアーキテクチャ固有かどうかはわかりません。それはアライメントでしょうか?これは私が心配する必要があることですか、それとも簡単な実装を進めることができますか?

事前にご協力いただきありがとうございます。

4

3 に答える 3

9

構造体のサイズは同じですが、配置要件が異なります。

構造体のアラインメントは、そのすべてのメンバーのアラインメントの最大値です。pix1文字しかないため、アライメント 1 も同様ですが、短いメンバーからのアライメント 2 がありpix2ます。その後の配置pix4はメンバーから配置を取得するpixelsため、最初のケースでは 1 で、2 番目のケースでは 2 です。

配列のすべてのメンバーが適切に整列されるようにするために、構造体のサイズはその整列の次の倍数に切り上げられます。どちらの場合も のサイズpixelsは 24 ですが、1 バイトありますmask。最初のケースではアラインメントが 1 であるため、25 はその倍数で 25 ですsizeof(pix4)が、2 番目のケースではアラインメントが 2 であるため、sizeof(pix4)次の偶数である 26 に切り上げる必要があります。

これは、すべてのプラットフォームで同じです。

于 2012-06-05T08:08:30.790 に答える
2

はい、それはアライメントと関係があります。コンパイラは変数を自然な境界に揃えたいので、shortは16ビット(2バイト)に揃えられます。したがって、shortを含む構造体も16ビット境界に配置されます。

于 2012-06-05T08:06:39.957 に答える
1

Linux32ビットでも同じ効果があります。

位置合わせの理由から、パディングと関係があります。

を使用するstruct pix1と、charのみが存在するため、struct pix4そのままにしておくことができます。ただし、を使用する場合struct pix2は、shortが含まれています。したがって、構造体全体を整列させる必要があります。これは、の配列であってもstruct pix4、すべての要素が整列されて、にクリーンにアクセスできるようにするためyです。

より詳細:strict pix42つの要素を持つ配列は次のようになります。

                +-----     [0]     -----+++-----    [1]     -----+
First version:  rgbayyrgbayyrgbayyrgbayyMrgbayyrgbayyrgbayyrgbayyM
Second version: rgbayyrgbayyrgbayyrgbayyM rgbayyrgbayyrgbayyrgbayyM
                ---------25--------------+ <- +1

なんで?ed部分は25バイトであるため---、これは奇数です。これは、最初のバージョンでは問題ありません。2番目の要素は奇数アドレスから問題なく開始できますが、2番目のバージョンでは問題ありません。そこでは、yyは常に偶数(整列)アドレス上にある必要があるため、struct pix426バイトになります。

于 2012-06-05T08:05:27.103 に答える