wwwheihei 发表于 2015-9-22 08:57:03

结构体字节对齐

#pragma pack (2) /*指定按2字节对齐*/
struct C
{
   char b;
   int a;
   short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/sizeof(struct C)值是8。

修改对齐值为1:

#pragma pack (1) /*指定按1字节对齐*/
struct D
{
   char b;
   int a;
   short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
sizeof(struct D)值为7。

怎么理解这个?从内存角度分析?

康小泡 发表于 2015-9-22 10:48:45

我的理解:
第一个你指定的是按两个字节对齐
char b;本来是一个字节,你指定了是按照2字节所以这里就是2字节
int a   ;本来是4字节,因为是按2对齐,所以依然是4字节
short c;本来是2字节,因为按2字节对齐,所以依然是2字节
结构体就为8字节

第二个,你指定按1个字节对齐,相当于是是多大就按多大来对齐
char b; 1字节
int a ;4字节
short c;2字节
结构体就为7字节

题外话
当你没有指定的时候,他会按照最大的一个来对齐,所以如果你没有指定的时候会出现以下的情况
char b ;按int型对齐 ,占4字节
int a ;占4字节
short ;按int型对齐,占4字节

当你改变以下他们的顺序,这个时候依然是int型占的最大,所以按int型对齐,但是有点不一样的是,这里不再是char b占4个字节,short c 占4个字节了,而是char b +short c一起在4个字节,所以这里的结构体会是8个字节
char b ;   
short c ;
int a ;

wwwheihei 发表于 2015-9-22 11:12:32

康小泡 发表于 2015-9-22 10:48
我的理解:
第一个你指定的是按两个字节对齐
char b;本来是一个字节,你指定了是按照2字节所以这里就是 ...

我看了如果没有指定按多少字节对齐 好像和字节偏移量有关?

wwwheihei 发表于 2015-9-22 11:13:45

康小泡 发表于 2015-9-22 10:48
我的理解:
第一个你指定的是按两个字节对齐
char b;本来是一个字节,你指定了是按照2字节所以这里就是 ...

为什么你却没提到呢?

wwwheihei 发表于 2015-9-22 13:48:37

康小泡 发表于 2015-9-22 10:48
我的理解:
第一个你指定的是按两个字节对齐
char b;本来是一个字节,你指定了是按照2字节所以这里就是 ...

题外话
当你没有指定的时候,他会按照最大的一个来对齐,所以如果你没有指定的时候会出现以下的情况
char b ;按int型对齐 ,占4字节
int a ;占4字节
short ;按int型对齐,占4字节

当你改变以下他们的顺序,这个时候依然是int型占的最大,所以按int型对齐,但是有点不一样的是,这里不再是char b占4个字节,short c 占4个字节了,而是char b +short c一起在4个字节,所以这里的结构体会是8个字节
char b ;   
short c ;
int a ;


你的这种算法好像和其他资料不一样?????

康小泡 发表于 2015-9-22 14:28:33

wwwheihei 发表于 2015-9-22 11:12
我看了如果没有指定按多少字节对齐 好像和字节偏移量有关?

是和结构体中所占字节最大的一个变量类型有关

康小泡 发表于 2015-9-22 14:30:12

wwwheihei 发表于 2015-9-22 13:48
题外话
当你没有指定的时候,他会按照最大的一个来对齐,所以如果你没有指定的时候会出现以下的情况
ch ...

自己测试吧,我只是说了我自己了解到的东西。

wwwheihei 发表于 2015-9-22 14:55:45

康小泡 发表于 2015-9-22 14:30
自己测试吧,我只是说了我自己了解到的东西。

其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。

类型

对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)

Char

偏移量必须为sizeof(char)即1的倍数

int

偏移量必须为sizeof(int)即4的倍数

float

偏移量必须为sizeof(float)即4的倍数

double

偏移量必须为sizeof(double)即8的倍数

Short

偏移量必须为sizeof(short)即2的倍数

康小泡 发表于 2015-9-22 16:40:22

wwwheihei 发表于 2015-9-22 14:55
其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处 ...

我知道这个。

wwwheihei 发表于 2015-9-23 08:37:10

康小泡 发表于 2015-9-22 16:40
我知道这个。

那我该如何把两种理解融汇贯通呢?还是两种说发不一样?

康小泡 发表于 2015-9-23 09:35:40

wwwheihei 发表于 2015-9-23 08:37
那我该如何把两种理解融汇贯通呢?还是两种说发不一样?

你说的这个,就是一个数据类型所占的大小,也就是我前面说过的,int 占4个字节,char占一个字节,这个是根据编译器来定的,不同的编译器他的大小是不一样的。你可以自己写代码测试一下,一个Int型所占的字节大小。然后对齐的那个是另外一知识点,在没有指定按照多少字节对齐的情况下,他是根据你这个结构体里面的所占字节最大的一个数据类型来对齐。 如果事先定义了,就会按照定义了的来对齐。
页: [1]
查看完整版本: 结构体字节对齐