構造体のアライメントというのを知らんかった

viviop
(絵は関係ないです)

C言語の構造体では構造体のアライメントというのがあるってのをしらなかったよ、って話。


C言語で、このバッファのエンディアンを変換しようーと処理書いている時、 char型とint型を1つずつ持つ構造体を使うと、リトルエンディアンのメモリの内容としては、下の様になっているのだろーと思っていたのですが、

typedef struct {
    char c;
    int i;
} prop_t;

/* main */
int main(int argc, char *argv[]) {
    prop_t prop;
    char* mem_p;
    mem_p = (char*)∝
    
    prop.c = 0x55;
    prop.i = 1;

    for (int i = 0; i < sizeof(prop_t); i++)
        printf("%02x", *(mem_p +i) );       

    return 0;
}
55 01 00 00 00

実行結果は下の様になってた。

55 00 00 00 01 00 00 00

3byte分どっから来たんだろーと思ってcharのmemberを増やして適当に値入れてみると、

typedef struct {
    char c;
    char c2;
    char c3;
    char c4;
    int i;
} prop_t;
55 aa 11 33 01 00 00 00

となった。なんか4byte単位で揃えたがってるっぽいな。

調べたらこういうことらしい。

C言語資料 構造体アライメントについて -PG’s PocketArms

__attribute__((packed))をつけたら、詰め込まれるようになった。

typedef struct {
    char c;
    int i;
}__attribute__((packed)) prop_t;
55 01 00 00 00

サンプルっちゅーかなんちゅーか。

#include 

/* define */
//// swith mode -- start
//#define ADDMEMBERS
#define STRUCTALIGNMENTPACKED
//#define OUTPUTFILE
//// swith mode -- end

#ifndef STRUCTALIGNMENTPACKED
typedef struct {
    char c;
#ifdef ADDMEMBERS
    char c2;
    char c3;
    char c4;
#endif
    int i;
} prop_t;

#else

typedef struct {
    char c;
#ifdef ADDMEMBERS
    char c2;
    char c3;
    char c4;
#endif
    int i;
}__attribute__((packed)) prop_t;
#endif

/* declare */


/* main */
int main(int argc, char *argv[]) {

    prop_t prop;
    char* mem_p;
    mem_p = (char*)∝
    FILE *fp;
    
    prop.c = 0x55;
#ifdef ADDMEMBERS
    prop.c2 = 0xAA;
    prop.c3 = 0x11;
    prop.c4 = 0x33;
#endif
    prop.i = 1;
    
    printf("sizeofchar_p: %lu\n", sizeof(char*) );

    for (int i = 0; i < sizeof(prop_t); i++) {
        printf("%02x", *(mem_p +i) );       
    }

#ifdef OUTPUTFILE   
    if ( (fp = fopen("/Users/ohton/test.bin", "wb")) == NULL) {
        printf("file open error!!\n");
        return -1;
    }
    
//  fwrite( &prop.c , sizeof(prop.c), 1, fp);
    fwrite( mem_p , sizeof(prop_t), 1, fp);
    fclose(fp); 
#endif

    return 0;
}

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

  • トラックバック 停止中
  • コメント (0)
  1. コメントはまだありません。