【关于结构体内存对齐问题】(上)

简介: 【关于结构体内存对齐问题】

一 .计算结构体的大小


首先我们来看一道例题:

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>structS1{
charc1;
inti;
charc2;
};
structS2{
charc1;
charc2;
inti;
};
intmain() {
printf("%d\n", sizeof(structS1));
printf("%d\n", sizeof(structS2));
return0;
}

如果没有了解过结构体内存对齐,我们很容易想到,char占1个字节,int占4个字节,S1总共占6个字节,S2占6个字节,打印的结果就是6和6,可当我们运行起来发现并不是,答案是12和8;

4c5f6fd8325f430f9fab23032e66b0db.png

51c8092d16b8465d9c64d31f60071c03.png

接下来我们就来讨论关于结构体在内存中是如何对齐的



二,关于结构体内存对齐规则


首先得掌握结构体的对齐规则:

1. 第一个成员在与结构体变量偏移量为 0 的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

对齐数 = 编译器默认的一个对齐数 与 该成员大小的 较小值 。

VS 中默认的值为 8

3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。


1)这里介绍一下偏移量和对齐数


偏移量:

我们把一个格子当做一个字节,最顶上那个位置我们叫做其实位置,相对偏移量为0的地方就是第一个格子,偏移量为1的地方就是第二个格子,以此类推,如图所示:

e61a9a5432434b1c8821cc405d982d23.png

对齐数:

对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值,举个例子,vs中的默认对齐数是8,char是一个字节,char类型的最大对齐数就是1,int是4个字节,int类型的最大对齐数就是4,double是8个字节,double类型的最大对齐数就是8.

目录
相关文章
|
7月前
|
编译器 Linux C语言
结构体内存对齐
结构体内存对齐
61 0
|
7月前
|
编译器 Linux C语言
详解结构体内存对齐及结构体如何实现位段~
详解结构体内存对齐及结构体如何实现位段~
|
存储 程序员 C语言
结构体,联合体与位段
结构体,联合体与位段
65 0
|
4月前
|
存储 安全 C语言
结构体与联合体
结构体与联合体
37 0
|
7月前
|
存储 编译器 C语言
自定义类型:结构体(自引用、内存对齐、位段(位域))
自定义类型:结构体(自引用、内存对齐、位段(位域))
|
7月前
|
存储 编译器 C语言
结构体的内存对齐与位段
当我们描述一个人的年龄时我们可以使用,int age = 18;但是如果我们要描述一个人呢?很显然我们无法仅靠一个age就实现对一个人的描述,所以就有了结构体,在结构体中我们可以包含多种类型的数据,这样就可以实现对一个人的描述比如身高、爱好、体重等等
|
编译器 Linux C++
结构体的内存对齐
结构体的内存对齐
|
编译器 C++
结构体内存对齐问题
结构体重点😃 1.结构体内存对齐问题,是在计算结构体的大小时,对结构体成员在内存中的位置进行研究的问题。
|
C++
【关于结构体内存对齐问题】(下)
【关于结构体内存对齐问题】
106 0
|
编译器 Linux C语言
结构体的内存对齐与位段的实现
注意上面这两种结构体都是属于匿名结构体类型,不告诉你名字,这种结构体类型如果要使用必须在声明的时候就在后面定义变量,不能再到主函数里面引用,因为你不知道这个结构体的名字是什么,所以必须在声明的时候就定义变量。
93 0