struct字节对齐问题

struct自己对齐是面试中几乎必问的问题,但是真正十分清楚的人感觉很少,包括我自己,没有特别花时间研究下。

为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。这里主要使用VC2013,系统win7-64位测试。g++之类的没有尝试过。

两条规则:

1.在默认情况下,VC规定各成员变量存放的起始地址,相对于结构起始地址的偏移量,必须为该变量的类型占用字节数的整数倍,如Char偏移量为sizeof(char)即1的倍数,int 偏移量应该是4的倍数,double应该是8的倍数,如果是struct,则根据struct的第一个成员类型进行判断。

如果到某个成员,该成员的地址偏移量不是size整数倍怎么办,那就需要对上一个成员结束位置开始,补齐字节,直到地址值偏移量是下一个成员size的整数倍。如果是数组当成连续的成员看待。如果上一个成员是struct,那么上一个struct的totalSize 要根据struct的maxSize独立计算,才能得到正确的偏移量。

2.结构占用的总空间大小应该为,结构中占用最大空间的类型所占用的字节数的整数倍。

这里我测试了一下,这个最大的占用空间的类型,应该指的是基本类型,比如一个数组char a[5],这种情况要分开来开,不能当成大小为5的数组,而是要看成5个char类型;另外如果有个成员是另一个struct,那么这个struct的大小也不能当做是占用最大空间的类型,而应该是struct中size最大的成员为准。

最后强调一句吧,如果struct A中有struct B,则开头看structB的第一个成员;如果struct B后有其他成员,那么计算偏移量时,前边的成员struct B 要当成独立个体计算(也就是说满足规则1,2)。最后计算struct A中maxSize类型时,要考虑struct B中的所有成员

事实胜于雄辩

// StructSize.cpp : 定义控制台应用程序的入口点。
//

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

using namespace std;

// 空结构,空类,都是1
struct S0
{
};
/*
成员a类型char,偏移0,0是任何整数的整数倍,不补齐字节。
maxSize:sizeof(char) == 1
totalSize: 1  , totalSize % maxSize == 0,末尾不补字节
totalSize:1
*/
struct S1
{
	char a;
};
/*
成员a:类型char,偏移0,0%1==0,不补字节。
成员b:类型char,偏移1=sizeof(a),1%1==0, 不补字节。
maxSize: sizeof(char) == 1
totalSize: 1+1=2  , totalSize % maxSize == 0,末尾补字节 +0
totalSize:2
*/
struct S2
{
	char a;
	char b;
};
/*
totalSize:3
*/
struct S3
{
	char a;
	char b;
	char c;
};
/*
成员a:类型double,sizeof(double)==8,偏移0,0%8==0,不补字节。
成员b:类型char,偏移:8=sizeof(a),8%1==0, 不补字节。
maxSize: sizeof(double) == 8
totalSize: 8+1=9  , totalSize % maxSize != 0,末尾补字节 +7
totalSize: 9+7 = 16
*/
struct S4
{
	double  a;
	char b;
};
/*
totalSize:8
*/
struct S5
{
	int a;
	char b;
};
/*
成员a:类型short,sizeof(short)==2,偏移0,0%2==0,不补字节。
成员b:类型char,偏移:2=sizeof(a),2%1==0, 不补字节。
maxSize: sizeof(short) == 2
totalSize: 2+1=3  , totalSize % maxSize == 3,末尾补字节 +1
totalSize: 2+1+1 = 4
*/
struct S6
{
	short a;
	char b;
};
/*
成员a:类型short,sizeof(char)==1,偏移0,0%1==0,不补字节。
成员b:类型int,偏移:1=sizeof(a),1%sizeof(int)==1, 补字节 +3。
maxSize: sizeof(int) == 4
totalSize: 1+3+4=8  , totalSize % maxSize == 0,末尾补字节 +0
totalSize:8
*/
struct S7
{
	char a;
	int b;
};

/*
totalSize:16
*/
struct S8
{
	double a;
	int b;
};
/*
成员a:类型拆成5个char看,size==5,补字节 +0。
成员b:类型int,偏移:5=sizeof(a),5%sizeof(int)==1, 补字节 +3。
maxSize: sizeof(int) == 4 (注意不是sizeof(a)==5)
totalSize: 5+3+4=12  , totalSize % maxSize == 0,末尾补字节 +0
totalSize:12
*/
struct S9
{
	char a[5];
	int b;
};
/*
成员a:3==sizeof(S3)
成员b:偏移:3=sizeof(a),3%sizeof(char)==0, 补字节 +0。
maxSize: sizeof(char) == 1 (注意,包括S3最大的结构)
totalSize: 3+1=4  , totalSize % maxSize == 0,末尾补字节 +0
totalSize: 4
*/
struct S10
{
	S3 a;
	char b;
};

/*
成员a:16==sizeof(S4)
成员b:偏移:16=sizeof(a),16%sizeof(char)==0, 补字节 +0。
maxSize: sizeof(double) == 8 (注意,包括S4最大的结构,double)
totalSize: 16+1=17  , totalSize % maxSize == 1,末尾补字节 +7
totalSize: 17+7=24
*/
struct S11
{
	S4 a;
	char b;
};
/*
成员a:8==sizeof(S5)
成员b:类型char,偏移:8=sizeof(a),8%sizeof(char)==0, 补字节 +0。
maxSize: sizeof(int) == 4 (注意,包括S5最大的结构,int)
totalSize: 8+1=9  , totalSize % maxSize == 1,末尾补字节 +3
totalSize: 9+3=12
*/
struct S12
{
	S5 a;
	char b;
};
//sizeof(STemp1)==7
struct STemp1
{
	char a[7];
};
//sizeof(STemp2)==5
struct STemp2
{
	char a[5];
};
/*
成员a:7==sizeof(STemp1)
成员b:偏移:7=sizeof(a),7%sizeof(double)==7, 补字节 +1。
maxSize: sizeof(double) == 8
totalSize: 7+1+8=16  , totalSize % maxSize == 0,末尾补字节 +0
totalSize: 16
*/
struct S13
{
	STemp1 a;
	double b;
};
/*
成员a:1==sizeof(char)
成员b:偏移:1,1%sizeof(char)==0, 补字节 +0  (STemp1 第一个成员是char,要分开来看)
成员c:偏移:8=1+sizeof(char)*7,8%sizeof(char)==0, 补字节 +0  (STemp2 第一个成员是char,要分开来看)
成员d:偏移:13=8 +sizeof(char)*5,13%sizeof(doulbe)==5, 补字节 +3
成员d:偏移:24=13+3 +sizeof(double),24%sizeof(char)==0, 补字节 +0
maxSize: sizeof(double) == 8
totalSize: 25=24+1  , totalSize % maxSize == 1,末尾补字节 +7
totalSize: 32
*/
struct S14
{
	char a;
	STemp1 b;
	STemp2 c;
	double d;
	char e;
};

/*
成员a:sizeof(char)==1
成员b:偏移:1=sizeof(a),1%sizeof(double)==1, 补字节 +7。
成员c:偏移:16=1+7+8,16%sizeof(char)==0, 补字节 +0。
成员d:偏移:17=16+1,17%sizeof(int)==1, 补字节 +3。
成员e:偏移:24=17+3+4,24%sizeof(STemp2)==4, 补字节 +1。
maxSize: sizeof(double) == 8 (所有结构中找)
totalSize: 25 = 24+1  , totalSize % maxSize == 1,末尾补字节 +7
totalSize: 32 = 25+7
*/

struct S15
{
	char a;
	double b;
	char c;
	int d;
	STemp2 e;
};
/*
成员a:1==sizeof(char)*3
成员b:偏移:3,1%sizeof(char)==0, 补字节 +0  (S7 第一个成员是char,要分开来看)
成员c:偏移:11=3+sizeof(S7),11%sizeof(double)==3, 补字节 +5  (S4 第一个成员是double,要分开来看)
成员d:偏移:32=11 + 5 +sizeof(S4),32%sizeof(int)==0, 补字节 +0 (S4 第一个成员是int,要分开来看)
成员e:偏移:40=32 +sizeof(S5),40%sizeof(char)==0, 补字节 +0
maxSize: sizeof(double) == 8
totalSize: 41=40+1  , totalSize % maxSize == 1,末尾补字节 +7
totalSize: 48
*/
struct S16
{
	char a[3];
	S7 b;
	S4 c;
	S5 d;
	char e;
};



int _tmain(int argc, _TCHAR* argv[])
{
	cout << "sizeof( S0 ) = " << sizeof(S0) << endl;
	cout << "sizeof( S1 ) = " << sizeof(S1) << endl;
	cout << "sizeof( S2 ) = " << sizeof(S2) << endl;
	cout << "sizeof( S3 ) = " << sizeof(S3) << endl;
	cout << "sizeof( S4 ) = " << sizeof(S4) << endl;
	cout << "sizeof( S5 ) = " << sizeof(S5) << endl;
	cout << "sizeof( S6 ) = " << sizeof(S6) << endl;
	cout << "sizeof( S7 ) = " << sizeof(S7) << endl;
	cout << "sizeof( S8 ) = " << sizeof(S8) << endl;
	cout << "sizeof( S9 ) = " << sizeof(S9) << endl;
	cout << "sizeof( S10 ) = " << sizeof(S10) << endl;
	cout << "sizeof( S11 ) = " << sizeof(S11) << endl;
	cout << "sizeof( S12 ) = " << sizeof(S12) << endl;
	cout << "sizeof( S13 ) = " << sizeof(S13) << endl;
	cout << "sizeof( S14 ) = " << sizeof(S14) << endl;
	cout << "sizeof( S15 ) = " << sizeof(S15) << endl;
	cout << "sizeof( S16 ) = " << sizeof(S16) << endl;
	return 0;
}




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值