当前位置: 首页 > news >正文

【C语言】【结构体的内存对齐】计算结构体内存大小,有图解

计算结构体内存大小,需要用到结构体内存对齐的知识
来段代码看看什么是结构体对齐:

#include<stdio.h>
struct S1 
{char a;char b;int num;
};
struct S2
{char a;int num;char b;
};
int main()
{printf("%zd\n", sizeof(struct S1));printf("%zd", sizeof(struct S2));
}

在这里插入图片描述
两个结构体包含的变量类型相同,但计算出来的内存大小不同,这就说明两个结构体在内存中的存储方式不同

结构体的存储规则就是:内存对齐

1.对齐规则:

  1. 结构体的第⼀个成员对⻬到相对结构体变量起始位置偏移量为0的地址处
  2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。 对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。
  • VS中默认的值为8
  • Linux中没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
  1. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的 整数倍。
  2. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。

1.1先用上面的代码解释前3条

在这里插入图片描述
第一个元素分别存到初始位置,char占 1 个字节

在这里插入图片描述
char类型占 1 个字节,小于VS默认的 8 个字节,所以存char时,每个对齐数都是 1 的倍数,可以紧挨着存 1 个字节
int 类型占 4 个字节,小于VS默认的 8 个字节,所以存 Int时,从对齐数 4 的位置开始存 4 个字节
由于存入的顺序取决于初始化结构体中变量的顺序,所以S1中接着存了 int 类型的,S2中接着存了 char类型的
在这里插入图片描述

数据存完之后,检验总内存大小是否是变量中最大对齐数的整数倍。如果是,最终内存大小就决定了;如果不是,还要再占内存直到补到倍数为止。蓝色的单元格表示浪费掉的内存。

所以最终结果:S1占 12 字节内存,S2占 8 字节内存。

1.2嵌套结构体计算大小

#include<stdio.h>
struct S3
{double d;char e;int i;
};
struct S4
{char j;struct S3 s3;double k;
};
int main()
{printf("%zd\n", sizeof(struct S3));printf("%zd", sizeof(struct S4));
}

根据前三条规则,可以计算出S3的内存为 16
所以第一个printf打印出来的是 16
在这里插入图片描述
在这里插入图片描述

S3中最大元素的内存是 8 个字节,所以存储S3的对齐数是 8 ,存入8 个字节;此时对齐数是 16 ,正好符合double类型内存(8个字节)的整数倍。存完double后对齐数是24。最后,因为24不是最大内存数 16 的倍数,所以从24到32之间的内存浪费掉。

第二个printf打印的是 32
在这里插入图片描述

2.内存对齐的性能原因:

数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬。原因在于,为了访问未对⻬的内存,处理器需要作两次内存访问;⽽对⻬的内存访问仅需要⼀次访问。假设⼀个处理器总是从内存中取8个字节,则地址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数,那么就可以⽤⼀个内存操作来读或者写值了。否则,我们可能需要执⾏两次内存访问,因为对象可能被分放在两个8字节内存块中。
总体来说:结构体的内存对⻬是拿空间来换取时间的做法。

那么在设计结构体的时候,既要满足对齐,又要节省空间,可以将占空间小的成员尽量聚集在一起:

#include<stdio.h>
struct S1
{char a;char b;int i;
};
struct S2
{char a;int i;char b;
};
int main()
{printf("%zd\n", sizeof(struct S1));printf("%zd\n", sizeof(struct S2));return 0;
}

在这里插入图片描述

3.修改内存对齐数:

#pragma这个预处理指令,可以修改默认对齐数

#include<stdio.h>
#pragma pack(1) //将默认对齐数设置为 1
struct S
{char a;char b;int c;
};
#pragma pack() //恢复为默认对齐数
int main()
{printf("%zd\n", sizeof(struct S));return 0;
}

在这里插入图片描述

相关文章:

【C语言】【结构体的内存对齐】计算结构体内存大小,有图解

计算结构体内存大小&#xff0c;需要用到结构体内存对齐的知识 来段代码看看什么是结构体对齐&#xff1a; #include<stdio.h> struct S1 {char a;char b;int num; }; struct S2 {char a;int num;char b; }; int main() {printf("%zd\n", sizeof(struct S1))…...

Intel 700 800系网卡升级支持WOL UEFI PXE方法

Intel 700 800系网卡默认的NVM版本是不支持UEFI的&#xff0c;升级NVM也不能解决&#xff0c;需要将UEFI driver 包到NVM里。操作步骤如下&#xff1a; 1. 下载Preboot软件包&#xff0c;有Windows和Linux版本&#xff0c;本次使用Linux版本做示例。 Intel Ethernet Connecti…...

vue3 - 使用 xlsx 库将数据导出到 Excel 文件

GitHub Demo 地址 在线预览 xlsx是由SheetJS开发的一个处理excel文件的JavaScript库。它可以读取、编写和操作 Excel 文件 安装xlsx npm install xlsx --save实现一个通过的数据导出工具类 import * as XLSX from xlsx/*** description: 导出excel* param {any} dataList* p…...

机器学习,深度学习

一 、Numpy 1.1 安装numpy 2.2 Numpy操作数组 jupyter扩展插件&#xff08;用于显示目录&#xff09; 1、pip install jupyter_contrib_nbextensions -i https://pypi.tuna.tsinghua.edu.cn/simple 2、pip install jupyter_nbextensions_configurator -i https://pypi.tuna.t…...

【性能测试】jmeter连接数据库jdbc

一、下载第三方工具包驱动数据库   1. 因为JMeter本身没有提供链接数据库的功能&#xff0c;所以我们需要借助第三方的工具包来实现。 &#xff08;有这个jar包之后&#xff0c;jmeter可以发起jdbc请求&#xff0c;没有这个jar包&#xff0c;也有jdbc取样器&#xff0c;但不能…...

蓝桥等考Python组别二级007

第一部分:选择题 1、Python L2 (15分) 下面哪个不是Python的基本数据类型?( ) 布尔型整数型指针型字符串正确答案:C 2、Python L2...

Java如何解决浮点数计算不精确问题

有的时候博客内容会有变动&#xff0c;首发博客是最新的&#xff0c;其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址[1] 面试题手册[2] 系列文章地址[3] 1. 什么是浮点数计算不精确问题? 在 Java 中&#xff0c;浮点数计算不精确问题指的是使用浮点数进…...

一图读懂「五度易链」企业创新服务解决方案,打造卓越营商环境!

“五度易链”紧密围绕园区企业及产业发展需求&#xff0c;基于数据积累和应用&#xff0c;创新企业服务机制&#xff0c;提升企业服务效能&#xff0c;以数字化手段为企业发展纾困解难&#xff0c;赋能企业高质量发展。并帮助园区在运营方面打破数据壁垒&#xff0c;实现数据监…...

软件工程 第一次随堂练习

以下答案是经过人工智能生成&#xff0c;个人理解得出的答案&#xff0c;若有不同见解&#xff0c;请在评论区留言或私信 说明下列需求分别属于下面的哪种类型&#xff0c;为什么&#xff1f; A.业务需求 B.用户需求 C.系统级&#xff08;功能&#xff09;需求 D.性能需求 E.质…...

在 Esp32 摄像头上实现边缘脉冲 FOMO 物体检测

轻松在 Esp32 相机上运行边缘脉冲 FOMO 物体检测的世界最佳指南。即使您是初学者 介绍 对象检测是检测图像内感兴趣的对象的任务。直到几年前,由于模型的复杂性和要执行的数学运算的数量惊人,这项任务还需要强大的计算机来完成。 然而,由于像Edge Impulse这样的平台,初学者…...

crypto:RSA

题目 利用代码跑一下解码 import gmpy2 e 17 p 473398607161 q 4511491 d gmpy2.invert(e,(p-1)*(q-1)) print(d)总结 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是一种非对称加密算法&#xff0c;常用于数据加密和数字签名。它基于两个大素数的乘积难以分解的数…...

APP产品经理岗位的具体内容(合集)

APP产品经理岗位的具体内容1 1、负责项目产品团队的管理工作&#xff0c;对项目产品团队考核目标负责; 2、全面负责“工务园”所有产品&#xff0c;全方位负责其生命周期管理; 3、按照产品管理相关的计划和规范&#xff0c;对产品版本的更新及发布负责&#xff0c;完善产品的…...

java 入门-使用eclipse、javaFX、SceneBuilder进行图形界面开发

个人是 一直在开C# CS端开发 &#xff0c; 目前 公司的软件 基本都使用了java作开发。 为了更好适应环境&#xff0c;我也只能再次学习这个陌生的开发工具。 java 的开发界面非常不友好 &#xff0c;对于我这样的初学者只能是借助插件来进行界面与后台联动&#xff0c; 上网度…...

集度汽车(武汉java)一面

hashMap底层结构&#xff0c;hash算法的好处是什么&#xff0c;为什么采用数组加链表&#xff0c;数组有哪些特性&#xff08;内存地址连续&#xff0c;查找快&#xff09;&#xff0c;怎么解决哈希碰撞&#xff0c;链地址法&#xff1b;并发编程需要注意哪些地方&#xff0c;如…...

虹科分享 | 为工业机器人解绑,IO-Link wireless无线通讯技术可实现更加轻量灵活的机器人协作

背景 机器人是一种能够半自主或全自主工作的智能机器。中国电子学会组织发布的《中国机器人产业发展报告&#xff08;2022年&#xff09;显示&#xff0c;近些年&#xff0c;我国机器人市场规模持续快速增长&#xff0c;“机器人”应用不断拓展深入&#xff0c;预计五年年均增…...

【PickerView案例10-国旗选择界面02 Objective-C预言】

一、好了,我们继续来实现这个国旗选择界面: 1.它的界面里面,是不是很简单,就一个UIPickerView,就完事儿了 然后,显示的每一行内容呢, 1)一个文字Label 2)一个图片 那大家应该有意识,它返回的应该是一个View,对吧, 代理方法里面,有一个返回View的,viewForRow…...

面试打底稿⑤ 项目一的第一部分

简历原文 抽查部分 项目描述 该项目旨在服务广州地区的快递物流&#xff0c;实现了下单、快递员取派件、订单转运单、线路规划、网点设置等功能。 责任描述 登录系统优化&#xff0c;双token三验证模式实现设置token状态、提高登录安全性的效果 模拟问答 1.能简单介绍一下…...

PSINS工具箱学习(三)让AI解释PSINS中的各种卡尔曼滤波函数

原始 Markdown文档、Visio流程图、XMind思维导图见&#xff1a;https://github.com/LiZhengXiao99/Navigation-Learning PSINS 中的 Kalman 滤波代码都在百行以内&#xff0c;没调用什么函数&#xff0c;而且通用性很强&#xff0c;拿去让 AI 解释&#xff0c;效果挺好。 文章目…...

多边形碰撞检测算法

1、AABB碰撞检测算法 AABB碰撞检测指轴对齐碰撞箱(Axis-aligned Bounding Box)&#xff0c;是分别从x轴向和y轴向进行碰撞检测的算法。即对于需要检测的物体A和物体B我们需要将其用A盒和B盒套起来&#xff0c;判断A盒和B盒在x轴向和y轴向是否发生碰撞&#xff0c;只有在x轴向和…...

【C/C++笔试练习】——printf在使用%的注意事项、for循环语句的三个条件、运算符优先级、删除公共字符

文章目录 C/C笔试练习1.%符号在printf用作格式说明符的注意事项&#xff08;1&#xff09;输出%5.3s&#xff08;2&#xff09;判断%中小数点含义 2.for循环语句的三个条件&#xff08;3&#xff09;判断循环次数&#xff08;4&#xff09;判断循环次数 3.运算符优先级&#xf…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...