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++知识库 -> 结构体在内存中的对齐规则及#pragma pack(n)应用 -> 正文阅读

[C++知识库]结构体在内存中的对齐规则及#pragma pack(n)应用

最近在看之前项目上的代码,发现了#pragma pack(n)这个预处理语句,就看不太懂,自己的C语言基础还停留在大学学的那半学期的水平,一通扒拉,发现了这么一个知识点,记录一下。

那这个预处理语句的作用是什么呢,其实就是要求编译器对结构体进行分配内存时按照我们要求的规则进行对齐并分配内存。那这是什么意思呢,这就要从结构体的默认对齐规则开始说起。假设我们要定义了一个这样两个结构体:

struct aa {
       char a;
       int b;
       double c;
} 


struct bb {
       char a;
       double b;
       int c;
} 

结构体aa和bb他们占用内存一样吗,如果一样的话他们占用的内存大小是13(1+4+8)吗?其实,他们占用的内存空间即不一样而且还都不是13。这是为什么呢,其实这就是结构体默认的对其导致的,结构体的对其的规则总结起来有三条

1.第一个成员变量对齐到结构体初始位置,即0偏移处

2.从第二个成员变量开始,对齐到该变量对齐数的整数倍数处

3.结构体的最终大小必须是成员变量中最大对齐数的整数倍

按照这三条规则我们分别来看结构体aa和结构体bb分别分配多少内存,首先来看aa的情况,根据规则1,a从0开始偏移,因为是char类型,占一个字节。再看吧,根据规则2,对其到该变量的整数倍,又因为数据类型是int,占4个字节,所以从第5个字节开始放,同理,因为c是double,占8个字节,所以从第九个字节开始放。所以结构体aa的内存分配情况如下图所示,总共占用了16个字节:

接着我们看一下结构体bb,根据规则1,规则2,a,b,c的对其方式如下,但是根据规则3

结构体的最终最终大小要为最大对齐数的整数倍(3*8=24),所以,我们要补上最后的四个字节。

说到这里,结构体对齐规则就介绍完成了,接下来,说会前面的pragma pack(n),他的作用就是忽视掉这些默认规则,按照开发人员的自己的意愿来对其,其中这个n指定的就是对的字节数,这里的n必须是2的阶乘,他要配合#pragma pack(push)和#pragma pack(pop),直接看代码:

#include <stdio.h>


struct aa {
       char a;
       int b;
       double c;
} A;
struct bb {
       char a;
       double b;
       int c;
} B;

#pragma pack(push)
#pragma pack(1)
struct cc {
       char a;
       int b;
       double c;
} C;
#pragma pack(2)
struct dd {
       char a;
       double b;
       int c;
} D;

#pragma pack(pop)

int main()
{
    printf("A大小为:%d \n", sizeof(A));
    printf("B大小为:%d \n", sizeof(B));
    printf("C大小为:%d \n", sizeof(C));
    printf("D大小为:%d \n", sizeof(D));
}

?代码的输出结果为:

A大小为:16 
B大小为:24 
C大小为:13 
D大小为:14 
按 <RETURN> 来关闭窗口...

在上面的代码中,最先定义的两个结构使用的默认的对其规则,我们进行了验证,从#pragma pack(push)这里开始,我们分别使用了,字节数是1和2的对齐规则进行结构内存分配,所以,C和D内存分配情况分别是13(1+4+8)和14(2+4+8)最后#pragma pack(pop) 恢复默认的对齐规则,这里#pragma pack(push)和#pragma pack(pop)需要配合使用。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-01-11 23:48:36  更:2022-01-11 23:51:06 
 
开发: 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年11日历 -2024/11/24 11:11:48-

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