字对齐问题 .

来源:互联网 发布:java时间戳转换成分钟 编辑:程序博客网 时间:2024/06/05 04:33

看结构体和共用体部分的时候,遇到了一个新名词“内存对齐”。先引入问题。如下:
1 struct student
2 {
3      char name[20];
4      int age;
5      char sex;
6      char phone[15];
7 };
8 struct student p1;

  sizeof(p1)=?
  这个很简单得出答案,即20+4+1+15=40Byte。如果将phone[15]改为phone[16],结果是44。难道不是41吗?
  这里便要引入内存对齐的概念。内存为了提高访问效率,规定以结构体中最大的基本单位长度为对齐标准。即实际分配的内存大小是对齐标准的整数倍(必要条件)。在上面的结构体中,最大的基本类型是int。因此以4Byte为对其标准。所以实际内存大小应该为4的整数倍,即为44Byte。
  也许你有疑惑:name[20]不是要20Byte吗,为什么以4Byte为对齐标准?请注意这里的基本类型。name[20]是一个字符串数组,数组属于复合的数据类型。复合的数据类型还有结构体,共用体。基本的数据类型是整型,字符型,浮点型。如果你还有不解,那么看下题:
 1 struct score
 2 {
 3     float english;
 4     float math;
 5     float computer;
 6 };
 7
 8 struct student
 9 {
10     char name[10];
11     int age;
12     char sex;
13     struct score st_score;
14 };

  在student结构体中含有数据类型为struct score这样的变量。struct score的大小为12Byte,也是struct student结构体中最大的数据类型,但是我们的对齐标准是4Byte,就如我们刚说的那样,内存的对齐标准是取结构体中最大的基本数据类型,这里我们取sizeof(int)。
  再看下面的问题:
 1 union data1
 2 {
 3     int i;
 4     char c;
 5     char str[9];
 6 };
 7
 8 struct data2
 9 {
10     int i;
11     char c;
12     char str[9];
13 };

  sizeof(struct data1)=?
  sizeof(struct data2)=?
  对于前者,由于共用体的存储大小由最大的成员来决定,因此上题中共用体的存储大小为9Byte,考虑到内存对齐,它以sizeof(int)=4Byte来对齐,因此实际内存分配大小是12Byte。对于后者,存储大小是4+1+9=14Byte,这个结构体以4对齐,因此实际分配大小为16Byte。
  现在你应该对于共用体和结构体的内存对齐有所了解了。那么再接着往下看:
1 struct data
2 {
3     char c;
4     double d;
5     char ch;
6 }

  sizeof(struct data)=?
  有了上面的理解,10肯定不会是答案,那么会是16吧。也错。正确答案是24。你可能会感到莫名其妙:按照上面所说的方法,以8为对齐标准,那么10不是8的倍数,那就是16呀。为什么呢?请你耐心看下面。
  首先我们知道结构体变量是分配的连续内存空间。d毫无疑问是分配8Byte,对于d“前面”的c,按照对齐标准我们应该分配8Byte,而d后面的ch,按照对齐标准也应该分配8Byte。因此结果是24。
  如果这样:
1 struct data
2 {
3     double d;
4     char c;
5     char ch;
6 }

  sizeof(struct data)=16。
  因为内存没必要分别为c和ch分配8Byte来进行对齐,将它们放在一个8byte里就可以实现内存对齐。上面在引入内存对齐概念的时候,用括号特别注释必要条件便是说明此处内容。

 ====================================

tpyedef struct

{

char name[17];

int a;

char b

char sex[16];

}day;

分析:

1.首先选择最大数据类型为的字节对齐标准,是int

2.是否连续存储??

char name[17] 有17个字节,不是4的倍数,所以之后变为:20

int a;是4的倍数,子、占个字节。

char b;占一个字节但还是下面还有同种类型来弥补,所以他们可以相加后,还差多少才能被4整除,就是多少

char sex[16];  1+16 = 17;不能被4整除,只有最小的20才能被 4整除

 

3.sizeof(day) = 20 + 4 + 20 =44;

 

-------------------

 

tpyedef struct

{

char name[2];

int a;

char b;

int x;

char sex[15];

}work;

 

char name[2]  本身占2字节,但是不对齐,不是是4倍数,所以得占4字节

int a;刚好是4的倍数

char b; 本身占1字节,不是4的倍数,加上后面不是char型,所以只有变为4

char sex[15],占15字节,只有最小的16才是4 的倍数;

 

所以:sizeof(work) = 4+4+4+4+16=32;

如:把最后一个改为:char sex[9] 本身占有0字节,但是只有最小的12,才是4的倍数

所以:sizeof(work) = 4+4+4+4+12=28;

 

===========================

 

tpyedef struct

{

char name[2];

int a;

char b;

int x;

char sex[15];

}work;

 

如何改造成占为最小的内存呢???

 

tpyedef struct

{

char b;

char name[2];

char sex[15];

int a;

int x;

}work;

tpyedef struct

{

int a;

int x;

char b;

char name[2];

char sex[15];

}work;

 

所以:sizeof(work) = 20(原来是:1+2+15,但不是4的倍数)+4+4=28;

原创粉丝点击