当前位置:网站首页>结构体内存对齐-C语言
结构体内存对齐-C语言
2022-08-04 05:31:00 【crazy__xieyi】
重点:计算结构体的大小; 内存对齐的原因;应对空间浪费的两种处理方式
1 计算规则:
1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的值为8
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
例1:
struct S1
{
char c1; // 自身大小为1 默认值为8 对齐数为1
int i; // 自身大小为4 默认值为8 对齐数为4
char c2; // 自身大小为1 默认值为8 对齐数为1
};
printf("%d\n", sizeof(struct S1)); //12
图解:
例2:
struct S2
{
char c1; // 自身大小为1 默认值为8 对齐数为1
char c2; // 自身大小为1 默认值为8 对齐数为1
int i; // 自身大小为1 默认值为8 对齐数为4
};
printf("%d\n", sizeof(struct S2)); //8
图解:
例3:
struct S3
{
double d; //自身大小为8 默认值为8 对齐数为8
char c; //自身大小为1 默认值为8 对齐数为1
int i; // 自身大小为4 默认值为8 对齐数为4
};
printf("%d\n", sizeof(struct S3)); //16
图解:
例4:结构体嵌套问题
struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4)); //32
图解:
2 内存对齐的原因
我们在了解了结构体内存对齐之后,并掌握了内存对齐计算规则,那么现在就可以接下来继续了解为什么会存在结构体内存对齐呢?
1. 平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。不同平台读取内存的机制可能不一样。
2. 性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
所以就会存在一个问题,这当中就会存在很多的内存空间会被浪费。总体来说:结构体的内存对齐是拿空间来换取时间的做法。
3 应对空间浪费的两种处理方式
一是在设计结构体的时候,我们既要满足对齐,又要节省空间,就要让占用空间小的成员尽量集中在一起。
struct S1
{
char c1;
int i;
char c2;
};
struct S2
{
char c1;
char c2;
int i;
};S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别。详细回看上面计算规则例1和例2.
修改默认对齐数
可以用#pragma 这个预处理指令,可以改变我们的默认对齐数。
例如:
#pragma pack(8) //设置默认对齐数为8
struct S1
{
char c1;
int i;
char c2;
};
#pragma pack() //取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。一般地,默认对齐数为2的N次方。
边栏推荐
- Windows10重置MySQL用户密码
- yoloV5 使用——训练速度慢,加速训练
- Deep learning, "grain and grass" first--On the way to obtain data sets
- LeetCode_22_Apr_2nd_Week
- MOOSE平台官方第二个例子分析——关于创建Kernel,求解对流扩散方程
- file permission management ugo
- Deep Learning Theory - Initialization, Parameter Adjustment
- [Copy Siege Lion Log] Flying Pulp Academy Intensive Learning 7-Day Punch Camp-Study Notes
- [Daily office][shell] Common code snippets
- FAREWARE ADDRESS
猜你喜欢
随机推荐
MNIST handwritten digit recognition, sorted by from two to ten
AWS uses EC2 to reduce the training cost of DeepRacer: DeepRacer-for-cloud practical operation
彻底删除MySQL教程
Machine Learning - Processing of Text Labels for Classification Problems (Feature Engineering)
Copy Siege Lions "sticky" to AI couplets
LeetCode_Nov_4th_Week
arm-3-中断体系结构
MNIST手写数字识别 —— 图像分析法实现二分类
第一章 绪论
A code example of the PCL method in the domain of DG (Domain Generalization)
file permission management ugo
makefile基础学习
tensorRT5.15 使用中的注意点
Chapter One Introduction
Cut the hit pro subtitles export of essays
数据库的简述与常用操作指南
【Copy攻城狮日志】飞浆学院强化学习7日打卡营-学习笔记
题目1000:输入两个整数a和b,计算a+b的和,此题是多组测试数据
LeetCode_Dec_1st_Week
LeetCode_22_Apr_4th_Week