IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++:内存对齐(struct/union/field) -> 正文阅读

[C++知识库]C/C++:内存对齐(struct/union/field)

C/C++:内存对齐(struct/union/field)

原因

? 字节对齐主要是为了提高内存的访问效率

  • 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

  • 性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

对齐原则

  • 首个成员在与结构体变量偏移量为0的地址处

  • 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间

  • 变量对齐数 = Min(编译器默认对齐数,该成员大小)

  • 各成员变量对齐到自身对齐数的整数倍(嵌套结构体对齐到自身最大对齐数整数倍

  • 结构体总大小为所有最大对齐数(包含嵌套结构体的成员对齐数)的整数倍
    在这里插入图片描述

示例

1.不同顺序排列

? S1大小:12字节(1+3 +4 + 1+3);

? S2大小:8字节(1+1+2 + 4);

? 粗体为对齐填充字节。

struct S1
{
    char c1;
    int i;
    char c2;
};
struct S2
{
 	char c2;
    char c1;
    int i;
};

2.包含数组

? student大小:24(10+2+4+1+3+4)

? char name[10] 的本质是 10 个 char 变量,所以就把它当成 10 个 char 变量看就行了;

? 粗体为对齐填充字节。

struct student
{
	char name[10];
	int age;
	char sex;
	float score;
};

3.结构体嵌套

? student大小:32(4+13+7+8)

? st1大小:48(4+4+32+1+7

struct student
{
	int num;
	char name[13];
	double gender;
};
struct st1
{
	int age;
	struct student s1;
	char sex;
};

4.联合体嵌套

? 联合体对齐方式要适合其中所有的成员(整个大小为最大对齐数的整数倍)

? MyUnion大小:16(13+3

? st1大小:32(4+4+16+1+7),union1应按成员最大字节对齐数(8)对齐,整个结构体为double倍数

union MyUnion
{
	int num;
	char name[13];
	double gender;
};
struct st1
{
	int age;
	union MyUnion union1;
	char sex;
};

pragma指令

  • 使用伪指令#pragma pack (n),C编译器将按照**min(n, sizeof(a))**个字节对齐(a为某类型变量,n= 1,2,4,8,16)。
  • 使用伪指令#pragma pack (),取消自定义字节对齐方式。

示例

1.S1大小:6(1+1+4)

? S2大小:10(1+1+6+2),嵌套时按照min(2,sizeof(a))对齐

#pragma pack(2)
struct S1 {
	char a;
	long b;
};

struct S2 {
	char c;
	struct S1 d;
	char e;
};
#pragma pack()

2.S1大小:8(1+3+4)

? S2大小:16(1+3+8+1+3),嵌套时按照min(8,sizeof(a))对齐

#pragma pack(8)
struct S1 {
	char a;
	long b;
};

struct S2 {
	char c;
	struct S1 d;
	char e;
};
#pragma pack()

位域

位域的声明和结构是类似的,有两个不同:

  • 位域的成员必须是 int、unsigned int、signed int、char等整形家族

  • 位域的成员名后边有一个冒号和一个数字

  • 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的

  • 一个位域必须存储在同一个字节中,不能跨两个字节

示例

? 连续相同类型可使用位域来节省空间(S1)

? 连续不同类型需按照对齐规则分配空间(S2)

? 含位域的结构体嵌套对齐规则与普通嵌套相同(S3)

struct S1 {
	int i:8;
	int b:4;
	char a:3;
	double c;
};//16字节

struct S2 {
	int i:8;
	char a:3;
	int b : 4;
	double c;
};//24字节

struct S3 {
	char c;
	struct S2 d;
	char e;
};// 40字节

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:19:47  更:2022-07-21 21:20:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 2:54:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码