当前位置:网站首页>结构体的内存对齐
结构体的内存对齐
2022-06-24 19:38:00 【啊星_】
之前我们都知道int类型大小是4个字节,char类型为1个字节,double为8个字节等等。
但是结构体是由很多类型组成的,那么它的大小是多少呢?是所有类型相加之和还是另有算法?
接下俩我们将仔细的探讨它.
先来说结论:结构体大小不是所有类型大小的和,而是存在一种内存对齐的方式,使得结构体中类型按某种方式对齐。
具体是怎么样的对齐方式呢?
我们先来看以下代码:
struct S1
{
char c1;
int i;
char c2;
};
printf("%d\n", sizeof(struct S1));大小不是1+4+1=6个字节哦。我们先看结果:

结果是12.是不是很不符合常理呢.
接下俩废话不多说,直接上内存对齐规则,然后我再一一解析它:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
我们先一句话一句话来分析.
一.第一个成员在与结构体变量偏移量为0的地址处。
偏移量可以抽象的理解为在内存中的位置。后面在讲解中慢慢会理解的.非常容易
例如上面那个例子:
第一个成员是 char c1;
那么位于偏移量为0的地址处,这样画一下会更容易理解.

其中 0 - 16数字都是偏移量,数字2代表偏移量为2,16则代表偏移量为16.
那么按照第一条规则:第一个成员应该在偏移量为0的位置,我们放入其中:
就成了上图所示.看接下来一条规则:
2. 其他成员变量要对齐到某个数字(对齐数)的最小整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8
要对齐到对齐数的整数倍。首先看对齐数是编译器默认的和该结构体成员的较小值.
vs编译默认的是8,而我们下一个类型即第二个类型为int类型,大小为4个字节.
所以我们取较小的值,即4,所以对齐数是4.
要对其到4的整数倍,我们此时只能取4的1倍了,如果是0,则4的0倍也是0,而偏移量为0的地方已经被占用,所以只能取4的1倍,即在偏移量为4的地方,开始占用一个int字节大小,空出来的空间,如偏移量为1,2,3的地方被浪费掉,不用再理.如下图:

接下来,第三个成员是char c2 :
同样的办法,
vs编译默认的是8,而我们这个类型即char类型,大小为1个字节.
所以我们取较小的值,即1,所以对齐数是1.
然后对齐到1的最小倍数,既然是1的倍数,那肯定是多少都可以了,1,2,3,4都可,但是我们偏移量此时已经到了7的位置,所以下一个只能占用偏移量为8的位置,即8的倍数.
如下:

此时所有成员已经对其完毕,接着看第三条规则:
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
此时的最大对齐数为结构体成员中占用空间最大的。
结构体成员类型分别为:char、int、char
最大的类型是int,即4个字节,即最大对齐数为4个字节..
所以结构体的总大小为4的整数倍,注意此时已经占用了9个字节,不是8个字节!
因为偏移量包括0,所以此时只是偏移量为8,但已经占用了9个字节。
所以此时只能是4的3倍数,即12个字节。若是4的2的倍数,则是8,小于我们已经占用的字节了,所以8肯定不行。
所以综上,此结构体的大小为12个字节.
这样的懂了,那下面这样的代码该如何处置呢?
struct S4
{
char c1;
struct S1 s1;
double d;
};
printf("%d\n", sizeof(struct S4));
注:s1是上面例子的是s1
我们在S4结构体里嵌套了一个S1结构体变量s1,那这样我们该如何计算呢?
首先按照第一条规则,将c1放在偏移量为0的位置.

下面重点来了,下一个成员是一个结构体的变量,此时它便不再遵循第2条规则,直接看第4条规则:
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
正常来说,我们将此成员的大小和编译器默认的大小作比较取最小值,然后找它的最小整倍数对齐。但是如果成员是一个结构体,它便不在按照自身的大小来计算,而是按照他自己的最大对齐数. 我们上面已经知道S1的最大对齐数是4,所以是4的倍数,此时只能从4的位置开始,即4的1倍数,如下:

接下来第三个成员是double类型,大小为8个字节,和编译器默认相同。那就取8,此时只能取8的2倍,即偏移量为16的位置.如下:

接着总大小为所有成员(包括嵌套的那个结构体)的最大对齐数的整数倍
他们的对齐数分别为1 4 8
所以最大对齐数是8,然后整数倍,只能是24,即8的3倍.
即此结构体的大小为24.我们看结果:

结果正确.
这里还有几道题,希望有时间可以做一下来巩固一下自己所学的知识。
//求S2结构体的大小
struct S2
{
char c1;
char c2;
int i;
};
//求S3结构体的大小
struct S3
{
double d;
char c;
int i;
};结果自己可以运行尝试一下哦,看看与自己运算的是否相符。
如有疑问的地方,欢迎私信联系哦.
题外话:
为什么存在内存对齐?
大部分的参考资料都是如是说的:
1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特
定类型的数据,否则抛出硬件异常
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访
问
结构体的内存对齐是拿空间来换取时间的做法.
---来源于比特就业课教材
那么结构体的内存对齐就到此为止了,还是一样,若是有疑问的地方,欢迎留言或者私信哦。
边栏推荐
- [Software Engineering] key points at the end of the period
- socket(2)
- 故障安全移动面板KTP900F Mobile下载程序提示无法下载,目标设备正在运行或未处于传输模式的解决办法
- Web攻击之CSRF和SSRF
- HTTP的缓存控制
- JMM 最最最核心的概念:Happens-before 原则
- Technology inventory: past, present and future of Message Oriented Middleware
- Redis-跳表
- Relationnet++: a representation of fusion of multiple detection targets based on transformer | neurips 2020
- interrupt、interrupted 、isInterrupted 区别
猜你喜欢

Web security XSS foundation 06

【个人实验报告】

A girl has been making hardware for ten years. 。。

Row and column differences in matrix construction of DX HLSL and GL glsl

Main steps of system test

Can AI chat robots replace manual customer service?

L2 元年,Arbitrum Nitro 升级带来更兼容高效的开发体验

Docker 安装 Redis-5.0.12,详细步骤

AQS source code analysis

软件设计的七大原则
随机推荐
How to solve the problem that the computer suddenly can't connect to WiFi
堆内存分配的并发问题
ACL (access control list) basic chapter - Super interesting learning network
重磅!法大大上榜“专精特新”企业
2022-06-16 工作记录--JS-判断字符串型数字有几位 + 判断数值型数字有几位 + 限制文本长度(最多展示n个字,超出...)
04A interrupt configuration
Programmers become gods by digging holes in one year, carrying flags in five years and becoming gods in ten years
详细了解关于sentinel的实际应用
YGG recent game partners list
Technology inventory: past, present and future of Message Oriented Middleware
短视频商城系统,scroll-view如何自适应页面剩余高度
Concurrency of heap memory allocation
NIO、BIO、AIO
Valueerror: cannot take a larger sample than population when 'replace=false‘
Learning notes 23-- basic theory of multi-sensor information fusion (Part I)
A girl has been making hardware for ten years. 。。
Leetcode: push domino (domino simulation)
Servlet详解
The usage difference between isempty and isblank is so different that so many people can't answer it
Publicity of the second batch of shortlisted enterprises! Annual Top100 smart network supplier selection