[C语言](详细)结构体的内存对齐(规则、存在原因、默认对齐数的修改等+实例分析)

2023-05-16

总目录
1.结构体内存对齐的规则
2.实例图文分析
3.为什么存在结构体内存对齐(+实例分析)
4.修改默认对齐数
5.结构体成员的排序
6.最后

1.结构体内存对齐的规则

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

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
对齐数=编译器默认的对齐数与该成员大小的较小值

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

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

(vs的默认对齐数为8,linux没有默认对齐数)

2.实例图文分析

这里我们使用vs进行演示
例①
在这里插入图片描述

>由规则1 “第一个成员在结构体变量为0的地址处”,故c的位置在0地址处(橙色部分),又因为是char类型,只占第一个字节
>由规则2,该成员变量为int类型,大小为4个字节,比vs默认对齐数8要小,故i对齐到对齐数4的整数倍即下标为4的位置(绿色部分),并向下占用4个字节
>同理,d为double类型,大小与默认对齐数相同,故从i的结束位置向下找8的整数倍数,并占用8个字节
>蓝色部分即为结构体内存对齐遵循规则浪费的空间

执行程序的结果如下
在这里插入图片描述

>照应规则3: 由结果值为16,该结构体的最大对齐数为8,结构体总大小为16,为最大对齐数的整数倍

例②
在这里插入图片描述

>同例①一样,c1的位置从S2的起始位置0处开始
>由例①知,struct S1 s1的大小为16,大于默认对齐数,则对齐数为较小值8,故从对齐数的整数倍下标为8的地址处开始,并向下占用16个字节
>d1的大小是8个字节,与默认对齐数一致,故向下取8的整数倍,而24恰好为8的整数倍,则从24开始向下占用8个字节
>蓝色部分即为结构体内存对齐遵循规则浪费的空间

执行程序的结果
在这里插入图片描述

>照应规则4,例②嵌套了结构体(S1),且嵌套的结构体(S1)对齐到自身成员内最大对齐数8的位置,而结构体(S2)的总大小为32,恰好为S1的整数倍

3.为什么存在结构体对齐

大多参考资料说法:

1.平台原因(移植原因):并不是所有的硬件平台都能访问任意地址的任意数据,一些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。因为,当访问未对齐的内存时,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

书面语当然难以理解,举个例子
在这里插入图片描述

>上图为存在内存对齐,下图不存在内存对齐,假设系统一次读取4个字节
>当读取i的时候,上图先读取前四个块,再读取后四个块,一次可以读完i
>而下图第一次读前四个块,第二次读后四个块,将i分两次读完

可以看出内存对齐后的效率有所提升,由此可以得出结论
结构体的内存对齐是拿空间换取时间的做法

4.修改默认对齐数

不多说,看代码

#include <stddef.h>
#pragma pack(2)//修改默认对齐值
struct S
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//结束对默认对齐数的修改

int main()
{	
	printf("%d\n", sizeof(struct S));
	return 0; 
}

>上述代码块,在一定范围内将默认对齐数改为了2

5.结构体成员的排序

一个小建议,当使用结构体的时候可以适当的调整结构体成员的排序,因为不同的排序可能导致结构体的总大小有所差异,正确的排序可以占用更少的大小
简单举个例子

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

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

void main()
{
	printf("%d\n", sizeof(s1));//12
	printf("%d\n", sizeof(s2));//8
}

6.总结

如果能帮助到你的话不妨点个赞

学习路上一路加油!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[C语言](详细)结构体的内存对齐(规则、存在原因、默认对齐数的修改等+实例分析) 的相关文章

  • SVM 原理详解,通俗易懂

    看了该作者的文章 xff0c 瞬间膜拜了 xff01 讲得太好了 xff01 转自 xff1a http www blogjava net zhenandaci category 31868 html xff08 一 xff09 SVM的简
  • 线阵相机学习笔记(一)

    1 GigE Vision GigE Vision是由自动化影像协会AIA Automated Imaging Association 发起指定的一种基于千兆以太网的图像传输的标准 具有传输距离长 xff08 无中继时100米 xff09
  • 如何做一个软件项目经理? ----写给公司所有的开发人员

    第一部分 xff1a 软件项目经理的要求 首先是一个管理者 xff0c 其次熟悉某些工具 xff0c 某几种语言 xff0c 行业背景 xff0c 项目管理技能 软件项目经理面临的恶劣环境 xff0c 我们绝大部分软件企业运行在相对混乱的状
  • vector介绍和基本使用

    文章目录 一 vector介绍二 vector使用 1 constructor 2 iterator 3 capacity 4 Element access 5 Modifiers 三 vector迭代器失效问题 一 vector介绍 ve
  • PELCO(派尔高)协议解析及下载(转载)

    PELCO xff08 派尔高 xff09 协议解析及下载 沈雪瑜 在IBMS接口开发 中 xff0c 我们需要用到一些常用的协议 xff0c 而PELCO 派尔高 的监控器材在我国有很广泛的应用 PELCO有自己的传输控制协议 xff0c
  • STM32&nbsp;HAL库&nbsp;STM3…

    原文地址 xff1a STM32 HAL库 STM32CUBEMX KEIL TIM1 PWM 四路输出可调 一 作者 xff1a 用户2797410335 硬件 xff1a TM32F407VET6 8M晶振 xff0c JLINK JT
  • 海康设备网络SDK开发NET_DVR_GetDeviceConfig

    由于官方的例子中没有关于NET DVR GetDeviceConfig的示例 xff0c 在此记录一下 NET DVR GET FIELD DETECTION 获取区域入侵侦测配置 xff0c 避免其他小伙伴踩坑 这里只记录主要代码 xff
  • geoserver热图

    1 参考 GeoServer发布Heatmap wenglabs 博客园 Rendering Transformations GeoServer 2 21 x User Manual 2 下载 GeoServer 及wps插件 xff0c
  • arcgis的lyr样式转qgis的sld样式

    需求 xff1a arcgis样式lyr要发布到geoserver 先说最终技术路线 xff1a qgis安装slyr插件 xff0c lyr转成xml xff0c 再通过xml配图后导出sld 避免的操作 xff1a lyr直接导出sld
  • httpclient海康ISAPI透传

    可以使用海康SDK调用NET DVR STDXMLConfig进行透传 xff0c 但是这种方式仍然比较麻烦 SDK的透传其实就是http的包装 xff0c 可以完全撇开海康SDK xff0c 也就是通过http的方式获取或者设置 xff0
  • openlayers文字随线的方向

    在不使用ol ext时需要自己计算方向 效果 xff1a 核心代码 xff1a function styleArrow start end title var arrowLonLat 61 end 0 43 start 0 2 end 1
  • openlayer点沿线动画

    Marker Animation 核心代码 xff1a 开始动画 let lastTime 61 Date now let distance 61 0 function moveFeature event const speed 61 10
  • ol-ext沿线动画

    参考示例 ol ext Openlayers feature animation 核心代码 xff1a 核心代码 var anim controler function animateFeature if routeFeature anim
  • test

    package org my cameratest import java io File import java io FileOutputStream import java io IOException import org kobj
  • C#操作Excel做Chart并输出成图

    lt summary gt 创建Chart xff0c 并设置相关属性 最后按照固定路径输出成gif图 lt summary gt lt param name 61 34 saveDocPath 34 gt 保存图片路径 lt param
  • Arcgis分级时出现Too many unique values (> 65536).

    只需要把默认值改的更大一点就行了 解决方法 xff1a 在默认值后面多添加几个0 xff0c 嘿嘿 xff0c 这样就行了
  • LCD与LED液晶显示屏的区别

    什么是LCD LCD是液晶显示屏Liquid Crystal Display的全称 xff0c 主要有TFT UFB TFD STN等几种类型的液晶显示屏无法定位程序输入点于动态链接库上 笔记本液晶屏常用的是TFT TFT xff08 Th
  • arcgis中连接excel时出错

    在arcmap中直接右键jion就可以关联excel xff0c 但是这次想使用小工具组合成ModelBuilder xff0c 所以先使用Copy Rows工具 xff0c 但是总是出错 xff0c 结果是一个字符引起的错误 箭头所指的方
  • 招行闪电贷“您的额度已被暂停”

    打电话给招行 xff0c 招行解释说名下两笔贷款都违规了 一笔是借贷还旧贷 xff0c 一笔是转账记录的备注写了还某某某首付 需要专款专用 xff0c 的确都违规了 招行也说只能先还完当前所有贷款 xff0c 才能尝试恢复额度 xff0c
  • su 鉴定故障解决办法(转)

    su su root命令输入密码后出现鉴定故障错误 这是因为在安装linux系统时没有给root用户设置密码 xff0c 重新设置密码即可 1 设置root密码 sudo passwd root gt 如果没有登录密码 则提示输入新密码 4

随机推荐