Microsoft Windows数据的对齐

      注:以下内容选自cs:app  

在linux系统沿用的策略是2字节数据类型(如short)的地址必须是2的倍数,而较大的数据类型(如int,int*,float和double)的地址必须是4的倍数。注意,这个要求意味着一个short类型的对象的地址最低位必须等于0。类似地,任何int类型的对象或指针的地址的最低两位必须都是0.

       在Microsoft Windows对齐的要求更加严格----任何K直接基本对象的地址都必须是K的倍数,K=2,4,或8。特别地,它要求一个double和long long类型数据的地址应该是8的倍数。

举例说明Microsoft Windows中数据的对齐方式:

struct {
char *a;
short b;
double c;
char d;
float e;
char f;
long long g;
void *h;
}foo;

问题:

1.这个结构体中所有字段的字节偏移量是多少?

2.这个结构体的大小是多少?

3.重新排列这个结构体中的字段,以最小化浪费的空间,然后再给出重排过的结构体的字节偏移量和总大小。


解答1:


说明:g的偏移量为28+4是因为g变量大小为8字节,故其地址必须是8的倍数,但是28不是8的倍数故向后扩张为32成为8的倍数

解答2:


说明:

填充1:在偏移为28的地方存放变量g,因为g是8字节对齐,地址必须是8的倍数,28不是8的倍数,故向后便宜4个字节

填充2:结构的大小要满足是结构体成员中最大变量的整数倍,所以结构体必须的填充4字节来满足8字节对齐要求


解答3:

当所有的结构体数据元素的长度是2的幂的时候,一种行之有效的策略就是按照大小的降序排列结构体的元素。

struct {

double c;

long long g;

float e;

char *a;

void *h;

short b;

char d;

char f;

};


上述的试验在vs2010中进行的调试,代码如下:

#include <stdio.h>
#include <conio.h>
#include <iostream>
using namespace std;


typedef struct {
char *a;
short b;
double c;
char d;
float e;
char f;
long long g;
void *h;
}foo;
typedef struct {
long long g;
double c;
float e;
void *h;
char *a;
short b;
char f;
char d;
}foo2;
int main()
{
foo temp;
//printf("%d\n",sizeof(foo));
//cout<<sizeof(foo)<<endl;
cout<<"foo:"<<sizeof(foo)<<endl;
cout<<"a:"<<(size_t)(&(((foo *)0)->a))<<endl;
cout<<"b:"<<(size_t)(&(((foo *)0)->b))<<endl;
cout<<"c:"<<(size_t)(&(((foo *)0)->c))<<endl;
cout<<"d:"<<(size_t)(&(((foo *)0)->d))<<endl;
cout<<"e:"<<(size_t)(&(((foo *)0)->e))<<endl;
cout<<"f:"<<(size_t)(&(((foo *)0)->f))<<endl;
cout<<"g:"<<(size_t)(&(((foo *)0)->g))<<endl;
cout<<"h:"<<(size_t)(&(((foo *)0)->h))<<endl;


cout<<"foo2:"<<sizeof(foo2)<<endl;
cout<<"a:"<<(size_t)(&(((foo2 *)0)->a))<<endl;
cout<<"b:"<<(size_t)(&(((foo2 *)0)->b))<<endl;
cout<<"c:"<<(size_t)(&(((foo2 *)0)->c))<<endl;
cout<<"d:"<<(size_t)(&(((foo2 *)0)->d))<<endl;
cout<<"e:"<<(size_t)(&(((foo2 *)0)->e))<<endl;
cout<<"f:"<<(size_t)(&(((foo2 *)0)->f))<<endl;
cout<<"g:"<<(size_t)(&(((foo2 *)0)->g))<<endl;
cout<<"h:"<<(size_t)(&(((foo2 *)0)->h))<<endl;
getch();
return 0;
}

运行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值