C/C++ 知识积累 --(1) struct结构体大小的计算

来源:互联网 发布:淘宝签约卖家 编辑:程序博客网 时间:2024/06/07 06:31

最近因为某些原因,接触到一些C/C++比较基础的知识点,发现在这方面有些薄弱,故记录下来,作为积累。

首先,概念性的东西就不做记录。已知机器为了更加容易的取出struct里面的数据,会将里面的变量所占空间进行对齐。这是以空间换时间的一种方式。

因为数据所占字节数跟机器字长及编译器有关系,所以先列出常见的几种数据类型在不同的编译环境下所占字节数。

字节对应表类型16位32位64位char111char*(指针)248short222int244unsigned int244float444double888long448long long888unsigned long448上表示网上找的字节与类型对应关系,但实测中 Windows  VS2015编译器 long 字节数为 4 ,unsigned long 字节数为 4. 所以字节数应该与编译器有关。

1.默认对齐方式

在默认对齐方式下,结构体成员的内存分配满足下面三个条件

  1. 结构体第一个成员的地址和结构体的首地址相同
  2. 结构体每个成员地址相对于结构体首地址的偏移量(offset)是该成员大小的整数倍,如果不是则编译器会在成员之间添加填充字节(internal adding)。
  3. 结构体总的大小要是其成员中最大size的整数倍,如果不是编译器会在其末尾添加填充字节(trailing padding)。
示例:(32位 Windows VS2015)
struct s1 {char a;//1偏移量 0int b;//4偏移量 1  -> 4double c;//8偏移量 8char d;//1偏移量 16};struct s2 {int a;//4偏移量 0char b;//1偏移量 4char c;//1偏移量 5double d;//8偏移量 6->8};int main() {cout << "s1 size = " << sizeof(s1) << endl;cout << "s2 size = " << sizeof(s2) << endl;char stop = getchar();return 0;}

运行结果为:


对于S1结构体,分析见注释,按照 条件2 ,得出大小为 17,又根据 条件3 ,得出最终大小为24。对于结构体S2,得出大小为 16,符合条件。

2.指定对齐方式

可以使用#pragma pack(N)来指定结构体成员的对齐方式
对于指定的对齐方式,其成员的地址偏移以及结构的总的大小也有下面三个约束条件

  1. 结构体第一个成员的地址和结构体的首地址相同
  2. 结构体每个成员的地址偏移需要满足:N大于等于该成员的大小,那么该成员的地址偏移需满足默认对齐方式(地址偏移是其成员大小的整数倍);N小于该成员的大小,那么该成员的地址偏移是N的整数倍
  3. 结构体总的大小需要时N的整数倍,如果不是需要在结构体的末尾进行填充。
  4. 如果N大于结构体成员中最大成员的大小,则N不起作用,仍然按照默认方式对齐。



原创粉丝点击