结构体大小的计算
一:在没有嵌套的情况下:
1.结构体的第一个成员变量放在结构体在内存中存储位置的0偏移处开始
2.从第二个成员往后的所有成员,都放在一个对齐数(成员的大小和默认对齐数的较小值)的整数倍的地址处
3.结构体的总大小是结构体的所有成员的对齐数中的最大的那个对齐数的整数倍
举几个简单的例子:
struct stu{ int a; char b; int c; }; struct stu1{ char a1; char b1; int c1; };
可以看出stu大小为1,stu1大小为8
二:在嵌套了结构体的情况下:
如果嵌套了结构体的情况,嵌套的结构体对齐的自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍
举个简单的例子
struct stu2{ char a2; struct stu b2; //stu最大对齐数为4,所以在内存中[4]的位置开始存放 int c2; };
可以看出stu2大小为20
三:修改默认对齐数
修改默认对齐数用#pragma pack()
举个简单的例子:
#pragma pack(1)//修改默认对齐数 struct stu3{ double a3; int b3; char c3; }; #pragma pack()//取消修改
可以看出stu3大小为13
位段
1.位段的成员必须是int,unsigned int,signed int,char。
2.位段的空间上是按照需要以4个字节(int)或者一个字节(char)的方式来开辟的
3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
举个简单的例子:
struct stu4{ int a:2; int b:4; int c:10; int d:20; };
对于以上位段,int型,先开辟四个字节
计算总元素大小:2(bit)+4(bit)+10(bit)+20(bit)=36(bit)
4字节空间不够,再开辟4个字节,8个字节总大小为64bit,够用了,所以stu4的大小为8个字节.
接下来看看位段中的元素如何存储:
struct stu5{ char a:2; char b:4; char c:6; char d:8; };
首先我们知道一个char类型大小为1个字节,1个字节为8bit,stu5中的元素总大小为20bit,所以需要开辟3个字节(24bit)。
接下来给位段赋值:
struct stu5{ char a:2; char b:4; char c:6; char d:8; }s={2,5,10,11};
数据如何存储呢?不妨先把内存表示出来
[0000 0000][0000 0000][0000 0000]
首先存储顺序无非就两种情况:高位开始或者低位开始
假设从低位开始存储,那么第一个字节存储完a,b之后应该是一下情况:
[00 0101 10]
那么还剩下两个bit,是舍弃还是存c呢?我们先假设舍弃,那么s存储完之后应该是一下情况:
[00 0101 10][00 001010][00001011]
转换成16进制应该是:
[16 0a 0b]
我们再vc6.0中编写代码查看内存:
完全正确。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)