Chinaunix首页 | 论坛 | 博客
  • 博客访问: 250750
  • 博文数量: 53
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-01 10:17
文章分类

全部博文(53)

文章存档

2013年(53)

分类: C/C++

2013-11-06 22:50:51

对内存对齐的理解:

   (struct)内存对齐的规则是:

       1、对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据的偏移量必须是Min(编译器被指定的对齐字节数,该数据成员的自身长度)的倍数。

GCC中,Min(系统默认(4, 数据成员自身长度(char/short/int/double)

        2、在数据成员完各自对齐之后,结构体(或联合体)本身也要进行对齐,对齐将按照编译器被指定的对齐字节数和结构体(或联合体)最大数据成员长度中,比较小的那个进行。

GCC中,Min(系统默认(4, struct成员中最大的数据类型(char/short/int/double)

如:

1

#include

struct abcd{

    char a;

    char b;

    short c;

    char d;

};

int main()

{

    printf("sizeof(abcd)=%d/n",sizeof(struct abcd));// 运行结果:sizeof(struct abcd)=6

    return 0;

}

      在struct  abcd 中,最大的数据类型是short型。所以在数据成员各自对齐后,整个结构体(或联合体)在进行对齐的时候,按照short型(长度为2)对齐,因为min( 4, short(2) )=2;

 

再看另一个代码:

2

/*2010-09-03*/

#include

/*32位机器访问起始地址是4的倍数处的内存比较方便

 min(系统默认(4),数据成员自身长度)*/

struct node1{  //sizeof(struct node1)=8;

    char a1;  //1

    short b1; //2

    int c1;   //4

};

struct node2{  //sizeof(struct node2)=12;

    char a2;  //1

    int c2;   //4

    short b2; //2

};

struct id_all_char{//

    char id3[3]; //3

    char ver;    //1

    char revision;//1

    char flag;    //1

    char size[4]; //4

};

struct idid{

    char id3[3];

    char ver;

    char revision;

    char flag;

    int size;

}__attribute__((packed));//__attribute__((packed))用于告诉编译器不要对其进行内存对齐!

 

struct all_short{//sizeof(struct all_short)=6;而不是8!因为a,b,c三个都是short,所以a,b,c最大的数据类型是short,所以min(4,2)=2(short),所以最后整个struct按照short型(长度为2)对齐

    short a;//2

    short b;//2

    short c;//2

};

 int main(void)

{

    printf("sizeof(struct node1)=%d/nsizeof(struct node2)=%d/n",sizeof(struct node1),sizeof(struct node2));

    printf("sizeof(struct all_short)=%d/n",sizeof(struct all_short));

    printf("sizeof(struct id_all_char)=%d/n",sizeof(struct id_all_char));

    printf("sizeof(struct idid)=%d/n",sizeof(struct idid));

    return 0;

}

对于struct:
struct ST_DAT1
    {
        char cDatA;
        int nDatC;
        char cDatB;
    } stDblChr;
struct ST_DAT2
    {
        char cDatA;
        char cDatB;
        int nDatC;
    } stDblChr;
很显然,编译器在编译的时候,要做内存对齐的调整。由于两个struct中最长的变量都是int,占据了4个字节的内存空间,因此都会提升至int型。
对 ST_DAT1,cDatA紧接着是int型的nDatC,因此cDatA会自动提升成int。其实这个地方是由于分配了cDatA之后,剩下的内存空间 只有3个字节,不足以放下一个int型,要存储nDatC的时候,nDatC只有另起炉灶,放到一个新的4字节空间里面,因为cDatA自动提升成了 int。最后的cDatB,其后面没有东西了,也会自动提升成int型。因此ST_DAT1占据了12个字节(用sizeof检查)
对 ST_DAT2,cDatA,和cDatB两个写得相连,编译器,碰到cDatA,先分配一个字节给他,再碰到cDatB,由于和cDatA的数据宽度一 样,因此不会做提升,同意分配一个字节他,此时总共分配了两个字节。等编译器碰到nDatC,由于数据位宽不一样,就要做自动提升了,和前面的道理一样。 因此这个时候sizeof检查ST_DAT2占据了8个字节。

阅读(2865) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~