C语言结构体内存对齐
结构体内存对齐
如何计算结构体的大小?
首先得掌握结构体的对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处。(将第一个成员放在结构体内存的第0处)
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。(从0地址处开始,偏移量逐渐增减,每个字节加一,第二个成员开始,将成员的字节大小跟对齐数(VS2019编译器的默认对齐数是 8)进行比较,选两者中较小的,把该变量放到小的对齐数的偏移量地址上)
对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
- VS中默认的对齐数为8
- Linux - 没有默认对齐数的概念
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。(如果全部成员自身的的大小已经放入内存,但最后一个成员的尾字节所在的偏移量不是最大对其数的整数倍,则在最后要浪费空间直到刚好到整数倍为止)
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
struct S
{ //类型大小 VS默认对齐数 两者中小的对齐数char c1; // 1 8 1int i; // 4 8 4double d; // 8 8 8
};
int main()
{struct S s;printf("%d\n",sizeof(s)); //结构体大小为16,并不是简单的变量大小相加
}
为什么存在内存对齐?
大部分的参考资料都是这样说的:
1.平台原因(移植原因)︰不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
⒉.性能原因︰数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
总体来说︰
结构体的内存对齐是拿空间来换取时间的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到∶
1.让占用空间小的成员尽量集中在一起。
2.修改默认对齐数
之前我们见过了#pragma这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数。
#pragma pack(2) //设置默认对齐数为2
struct s1
{char c1;int i;char c2;
};
#pragma pack() //取消设置的默认对齐数,还原为默认
此时结构体大小为8,如果设置默认对齐数为1的话,则成员紧挨着存放,等于没有对齐
offsetof宏:
用于计算结构体中某变量相对于首地址的偏移量(以字节为单位)
函数原型:offsetof (type,member)
使用:
#include <stdio.h>
#include <stddef.h> //需要引入头文件
struct s1
{char c1;int i;char c2;
};
int main()
{printf("%d\n", offsetof(struct s1, c1)); //0,C1在偏移量为0的地址处printf("%d\n", offsetof(struct s1, i)); //4,i在偏移量为4的地址处printf("%d\n", offsetof(struct s1, c2)); //8,C2在偏移量为8的地址处return 0;
}
模拟实现offsetof宏:
#include <stdio.h>
struct A
{char a;int b;char c;double d;
};
#define OFFSETOF(struct_name,mem_name) (int)&(((struct_name *)0)->mem_name)
int main()
{//模拟实现宏offsetofprintf("%d\n", OFFSETOF(struct A, a));printf("%d\n", OFFSETOF(struct A, b));printf("%d\n", OFFSETOF(struct A, c));printf("%d\n", OFFSETOF(struct A, d));return 0;
}
解释:定义宏时,将0强制转换为结构体类型,只是0不再是个整型,而是个地址,是结构体的首地址,并没有真正去创建结构体变量,然后通过->找到相应的结构体变量,&取出该变量的地址,减去0地址,再强制类型转换为int型,就能输出变量相对于首地址的偏移量,这里没有减-0,因为没有意义,如果规定首地址是0x10,那最后强转为int之前就要减去首地址0x10,才是偏移量
C语言结构体内存对齐相关推荐
- C语言结构体内存对齐问题
参考博文:C语言结构体内存对齐问题 成员对齐: 以4字节对齐为例,如果自身类型小于4字节,则该成员的首地址是自身类型大小的整数倍:如果自身类型大于等于4字节,则该成员的首地址是4的整数倍.若内嵌结 ...
- 室友利用一把王者的时间就学会了【C语言结构体内存对齐】
文章目录 一.什么是结构体内存对齐? 二.结构体的对齐规则 结构体内存对齐规则的具体应用 三.为什么会存在内存对齐 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一.什么是结构体内存对齐? 从 ...
- c语言 char转int_图文并茂,一文讲透C语言结构体内存对齐
↑点击上方蓝色字体,关注"嵌入式软件实战派"获得更多精品干货. (以下有约5000字内容,建议收藏再读,推荐下载源码自行测试以加深理解.) 面试官:你知道C语言的结构体对齐吗? 应 ...
- C语言-结构体内存对齐
C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的 ...
- c语言结构体的对齐方式,C语言结构体内存的对齐知识详解
前言 在前面的章节中,我们谈到了C语言中整数以及浮点数的储存 今天,我们来谈一谈一些关于结构体内存的知识. 我们先来看一个例子: struct S1 { char c1; int i; char c2 ...
- printf打印结构体_工程师:这道题80%初学者都没做对!你确定搞懂结构体内存对齐了?...
这是工程师面试后的实际经历-- 这道经典.易错的关于C语言结构体内存对齐的题目,你真的会吗: 求32bit环境下以下结构体所占的字节数:typedef struct test_struct{ char ...
- 关于C语言中的结构体内存对齐与位段问题
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 结构体的内存对齐与位段 一.结构体的内存对齐 1.为什么会有内存对齐? 2.如何内存对齐 3. 如何在设计结构体的时候,既要 ...
- 语言结构体在内存的分布_结构体内存对齐,这篇文章给你彻底搞会!(干货收藏)...
脚本之家 你与百万开发者在一起 公众号:C语言编程 作者:薛定谔的coding猫 一.内存对齐的原因 1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上 ...
- 细讲C语言结构体(结构体内存对齐你懂了吗?)
结构体 结构体类型的声明 结构体自引用 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体 结构体的声明 结构体是一些值集合的,里面可以包括char,int,double等等的各种类型构成的 ...
- 【C语言】自定义类型——计算结构体内存对齐
文章目录 前言 一.结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 *结构体内存对齐 修改默认对齐数 结构体传参 结构体实现位段(位段的填充&可移植性) 二.枚举 枚举类型的 ...
最新文章
- 记录一次没有收集直方图优化器选择全表扫描导致CPU耗尽
- SAP QM 模块主数据
- vb.net机器学习-手写和本机数字识别-K均值和欧氏距离
- Linux综合练习——课件分发
- html5+php调用android手机图片,HTML5拍照上传图片Phonegap封装HTML5调用Android相机拍照上传到PHP端...
- LINUX给进程内容窗口改名的代码
- Android中应用程序获得系统签名权限(platform.x509.pem platform.pk8)下载地址
- PPAPI 插件编写
- H5+CSS前端特效源代码:可旋转动态日文片假名
- 时序数据获取 | Python实现时间序列数据集获取
- 淘宝店铺老店标识怎么显示 怎么淘宝老店标识申请
- gnu nano显卡测试软件,显卡天梯图2018年9月最新版 秒懂桌面显卡性能排行
- Lattice LSTM
- 【渗透测试工具beef】XSS渗透测试工具beef如何安装使用?
- 深度linux u盘启动安装教程,带你了解国产操作系统“深度(deepin)”之制作U盘启动教程...
- Android 12 小部件详解
- 计算机打开查看方式默认是什么样,如何设置电脑文件夹默认查看方式
- python-pyqt5-初识-2基本操作
- 敏之澳分享拼多多的宝贝标题要怎么写?
- 数字数据转换为字符数据_为什么替代数据对数字转换至关重要
热门文章
- U盘格式化后恢复,DiskGenius 4.9.6 海外注册版
- MATLAB线性规划相关函数用法
- mapgis6.7原创2019视频教程
- cwm oracle,ORA-06512: at OLAPSYS.CWM2_OLAP_UTILITY
- Zint生成多种条码及二维码
- Lantek钣金软件的介绍与安装
- java中模糊查询sql怎么写_java模糊查询sql语句
- 【行业专题报告】食品饮料、休闲零食、咖啡茶饮-专题资料
- smarty3中文手册
- android 开发种子文件,IT之家学院:如何制作种子文件和磁力链接