自定义类型(结构体、枚举、联合体)内存大小的计算方法

news2024/11/17 21:44:29

内存对齐

为什么会存在内存对齐?

大部分参考资料是这么说的:

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

总体来说,结构体的内存对齐是那空间换取时间的做法。

结构体

结构体的内存对齐规则

  • 结构体第一个成员放在偏移量为0的地址,其他成员要按照规则放在该成员对齐数的整数倍地址处,之后还需计算结构体总大小,就是结构体成员最大对齐数的整数倍。
  • 特殊情况:如果结构体中嵌套有结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小是所有成员中最大对齐数的整数倍。

修改默认对齐数

结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。

#pragma pack(8)    //设置默认对齐数为8
#pragma pack()     //取消设置的默认对齐数,还原为默认
#pragma pack(1)    //设置默认对齐数为1

位段

struct A
{
    int _a:2;
    int _b:5;
    int _c:10;
    int _d:30;
};
printf("%d\n", sizeof(struct A));

位段的内存计算

以上段代码为例:

  • 冒号后面的数字表示该成员为n位,结构体向最长的int对齐,前三个加起来为17位,超过2个字节,不到4个字节,但加上第四个成员30位,就超过4个字节,所以第四个成员需要对齐到4字节处,前三个成员合起来占4个字节,第四个成员占4个字节,共8个字节。
  • 结构体最大对齐数为4,8是4的整数倍,所以整个结构体的大小为8.

枚举

枚举==列举

比如:

  • 一周的星期一到星期日是有限的7天,可以一一列举。
  • 性别有:男、女、保密,也可以一一列举。
  • 月份有12个月,也可以一一列举
  • 颜色也可以一一列举。

我们可以使用 #define 定义常量,为什么非要使用枚举?

枚举的优点

  1. 增加代码的可读性和可维护性
  2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
  3. 防止了命名污染(封装)
  4. 便于调试
  5. 使用方便,一次可以定义多个常量

枚举的内存计算

enum Day//星期
{
    Mon,
    Tues,
    Wed,
    Thur,
    Fri,
    Sat,
    Sun
};
enum Sex//性别
{
    MALE,
    FEMALE,
    SECRET
};
enum Color//颜色
{
    RED=1,
    GREEN=2,
    BLUE=4,
    YELLOW
}

上面的 Day 、Sex 、Color 都是枚举类型,{ }内容都是枚举类型的可能取值,也就是枚举常量。
这些可能取值都是有值的,默认从0开始,一次递增1。也可以在定义的时候赋初始值,

比如上面Sex里的MALE为0,FEMALE为1,SECRET为2.
Color里的RED为1,GREEN为2,BLUE为4,YELLOW为5

联合(共用体)

联合的特点

  1. 成员共用同一块内存空间
  2. 联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
  3. 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

联合的内存计算

union Un
{
    int i;
    char c;
};
union Un un;

例中联合变量un的大小就是最大成员的大小4
特例:

union Un1
{
    char c[5];    //1*5=5
    int i;
};
//最大对齐数4,对齐之后:8
union Un2
{
    short c[7];   //2*7=14
    int i;
};
//最大对齐数4,对齐之后:16
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));


如上例这样,最大成员不是最大对齐数的整数倍,就要对齐到最大对齐数的整数倍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1485382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python绘制不同形状词云图

目录 1.基本词云图1.1 导入所需库1.2 准备词汇1.3 配置参数并生成词云图1.4 在Python窗口中显示图片1.5 效果展示1.6 完整代码 2. 不同形状词云图2.1 找到自己所需形状图片2.2 利用PS将图片设置为黑白色2.3 在代码中设置背景2.4 效果展示 1.基本词云图 1.1 导入所需库 import…

设计模式七:责任链模式

文章目录 1、责任链模式2、spring中的责任链模式Spring InterceptorServlet FilterNetty 1、责任链模式 责任链模式为请求创建了一个接收者对象的链,在这种模式下,通常每个节点都包含对另一个节点者的引用。每个节点针对请求,处理自己感兴趣…

备战蓝桥杯---动态规划的一些思想1

话不多说,直接看题: 目录 1.双线程DP 2.正难则反多组DP 3.换个方向思考: 1.双线程DP 可能有人会说直接贪心:先选第1条的最优路径,再选第2条最优路径。 其实我们再选第1条时,我们怎么选会对第2条的路径…

宝塔面板安装各种组件以及部署应用服务

在linux服务器安装宝塔面板 一、从宝塔官网下载exe安装包,安装命令从宝塔官网(https://www.bt.cn/)获取 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh二、安…

【JGit 】一个完整的使用案例

需求 生成一系列结构相同的项目代码,将这些项目的代码推送至一个指定的 Git 仓库,每个项目独占一个分支。 推送时若仓库不存在,则自动创建仓库。 分析 生成代码使用 Java 程序模拟,每个项目中模拟三个文件。Project.cpp 、Pro…

总结 HashTable, HashMap, ConcurrentHashMap 之间的区别

1.多线程环境使用哈希表 HashMap 不行,线程不安全 更靠谱的,Hashtable,在关键方法上加了synchronized 后来标准库又引入了一个更好的解决方案;ConcurrentHashMap 2.HashMap 首先HashMap本身线程不安全其次HashMap的key值可以为空(当key为空时,哈希会…

FNM和SFNM的区别

看图说话。 级联模式下,FNM模式,从片的中断都是同一个级别,因此从片如果有多个中断发生,中断之间不会抢占,只能按顺序处理。 级连模式下,SFNM模式,从片中断有优先级的区别,高优先级…

Qt外部调用进程类QProcess的使用

有的时候我们需要在自己程序运行过程中调用其他进程,那么就需要用到QProcess。 首先可以了解一些关于进程的相关知识:线程与进程,你真得理解了吗_进程和线程的区别-CSDN博客 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0…

7.1.1 selenium介绍及安装chromedriver

目录 1. Selenium的用途 2. 安装Selenium库 3. 安装chromedriver 1. 查看谷歌版本号​编辑 2. 找到最新版本及下载 3. 配置环境变量 4. 检测是否配置成功 5. 用python初始化浏览器对象检测: 6. 参考链接 1. Selenium的用途 在前面我们提到:在我…

NIO核心三:Selector

一、基本概念 选择器提供一种选择执行已经就绪的任务的能力。selector选择器可以让单线程处理多个通道。如果程序打开了多个连接通道,每个连接的流量都比较低,可以使用Selector对通道进行管理。 二、如何创建选择器 1.创建Selector Selector select…

ArduinoTFTLCD应用

ArduinoTFTLCD应用 ArduinoTFTLCD应用硬件连接软件导入库显示数字、字符显示汉字方案1方案2 显示图片 总结 ArduinoTFTLCD应用 对于手工喜欢DIY的人来说,Arduino驱动的TFTLCD被很多人使用,此处就总结一下,使用的是VScode的PlatformIO插件驱动…

Docusaurus框架——react+antd+echarts自定义mdx生成图表代码解释文档

文章目录 ⭐前言⭐Docusaurus框架渲染mdx内容💖 创建一个mdx文件💖 创建一个react jsx文件💖 mdx引入react的组件并渲染💖 mdx引入react的组件源代码内容 ⭐渲染一个echarts地图的代码解释文档💖 echarts 渲染地图&…

USLE模型-P因子的计算

首先需要下载土地利用类型数据集,查看我的相关文章 对于已有的10种土地类型代码,需要按水土保持措施P值表进行重分类。 10是耕地,且庆阳市坡度10-15度左右,所以赋给了3(最好再下个DEM计算一下,这里就统一用…

WebServer -- 注册登录

目录 🍉整体内容 🌼流程图 🎂载入数据库表 提取用户名和密码 🚩同步线程登录注册 补充解释 代码 😘页面跳转 补充解释 代码 🍉整体内容 概述 TinyWebServer 中,使用数据库连接池实现…

C++指针(三)

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 文章目录 前言 1.字符指针 1.1字符指针的概念 1.2字符指针的用处 1.3字符指针的操作 1.3.1定义 1.3.2初始化 1.4字符指针使用注意事项 2.数组参数,指针参数 2.1数组参数 2.1.1数组参数的概念 2.1…

NCT 全国青少年编程图形化编程(Scratch)等级考试(一级)模拟测试H

202312 青少年软件编程等级考试Scratch一级真题 第 1 题 【 单选题 】 以下说法合理的是( ) A :随意点开不明来源的邮件 B :把密码设置成 abc123 C :在虚拟社区上可以辱骂他人 D :在改编他人的作品前, 先征得他人同意 正确答案: D 试题解析&…

python模块和包概念与使用

python模块和包概念与使用 Python模块与包的关键概念 在Python编程中,模块和包是代码组织和管理的基石。以下是关于Python模块与包的核心要点: 模块: 模块是一个包含Python代码的.py文件,它可以定义函数、类、变量等。通过导入模…

水经微图Web版1.6.0发布

让每一个人都有自己的地图! 水经微图(简称“微图”)新版已上线,在该版本中主要新增了点线面图层分组样式设置、图层排序并按序绘制、KML支持矢量符号的存储、KML支持态势标绘要素存储和新增历史地图文本样式等。 现在&#xff0…

Leetcoder Day27| 贪心算法part01

语言:Java/Go 理论 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 什么时候用贪心?可以用局部最优退出全局最优,并且想不到反例到情况 贪心的一般解题步骤 将问题分解为若干个子问题找出适合的贪心策略求解每一个子…

使用plasmo框架开发浏览器插件,注入contents脚本和给页面添加UI组件

plasmo:GitHub - PlasmoHQ/plasmo: 🧩 The Browser Extension Framework plasmo是一个开发浏览器插件的框架,支持使用react和vue等技术,而且不用手动管理manifest.json文件,框架会根据你在框架中的使用,自…