C++ 结构体内存对齐

定义了两个结构体

 typedef struct Cmd {uint8_t ua;uint8_t ub;uint8_t uc;uint32_t ue;
} Cmd_t;typedef struct Cmd_tag {uint8_t value;uint8_t data[1]; // 将 data 定义为指向 Cmd_t 结构体的指针
} tag_t;

在实际使用中,看见前人的代码是,new 一块内存放两个结构体。我对内存大小有些疑惑。代码如下

void test2()
{int size = 9;unsigned char* pdata = new unsigned char[size];memset(pdata, 0, size);// 解释 pdata 为 tag_t* 类型的指针tag_t* pCmd = (tag_t*)pdata;pCmd->value = 1;// 将 pdata + 1 解释为 Cmd_t* 类型的指针,并将其赋给 data 成员Cmd_t*  p= (Cmd_t*)(pdata + 1);p->ua = 10;p->ub = 10;p->uc = 10;p->ue = 10;std::cout << "value: " << static_cast<int>(pCmd->value) << std::endl;std::cout << "Address of pCmd->value: " << static_cast<void*>(&pCmd->value) << std::endl;std::cout << "data->a: " << static_cast<int>(p->ua) << std::endl;std::cout << "Address of p->a: " << static_cast<void*>(&p->ua) << std::endl;std::cout << "data->ub: " << static_cast<int>(p->ub) << std::endl;std::cout << "Address of p->ub: " << static_cast<void*>(&p->ub) << std::endl;std::cout << "data->uc: " << static_cast<int>(p->uc) << std::endl;std::cout << "Address of p->uc: " << static_cast<void*>(&p->uc) << std::endl;std::cout << "data->ue: " << p->ue << std::endl;std::cout << "Address of p->ue: " << static_cast<void*>(&p->ue) << std::endl;delete[] pdata;
}

输出如下
在这里插入图片描述
解释:

 std::cout << "Size of tag_t: " << sizeof(tag_t) << " bytes" << std::endl;std::cout << "Size of Cmd_t: " << sizeof(Cmd_t) << " bytes" << std::endl;
// Size of tag_t: 2 bytes//Size of Cmd_t: 8 bytes

结构体 tag_t需要2 bytes
结构体 Cmd_t 需要 8 bytes

一开始我以为,new一块内存存放她两需要 2+8 =10 bytes
但是由于 将 pdata + 1 解释为 Cmd_t* 类型的指针,并将其赋给 data 成员

Cmd_t*  p= (Cmd_t*)(pdata + 1);

相当于 Cmd_tag.data 和 Cmd_t.ua公用一个字节的内存

所以new的时候只需要 9 bytes

.还有一个坑:
最开始计算Cmd_t大小时 ,我以为是7bytes. 后来发现C++ 结构体在这里右4字节对齐
可以观察输出, p->ue的地址比 p->uc的地址增加了 2
所以如果代码里,size =8 程序会崩溃

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

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

相关文章

MySQL第三次作业--DML语句(INSERT)

目录 一、在数据库中创建一个表student&#xff0c;用于存储学生信息 二、向student表中添加一条新记录&#xff0c;记录中id字段的值为1&#xff0c;name字段的值为"monkey"&#xff0c;grade字段的值为98.5 三、向student表中添加多条新记录&#xff1a; 2,&qu…

详解动态规划之01背包问题及其空间压缩(图文并茂+例题讲解)

1. 动态规划问题的本质 记忆化地暴力搜索所有可能性来得到问题的解 我们常常会遇到一些问题&#xff0c;需要我们在n次操作&#xff0c;且每次操作有k种选择时&#xff0c;求出最终需要的最小或最大代价。处理类似的问题&#xff0c;我们一般需要遍历所有的可能性(相当于走一遍…

SpringMVC核心组件之HandlerMapping详解

文章目录 前言一、AbstractHandlerMapping抽象类initApplicationContextgetHandler 二、MatchableHandlerMapping类二、AbstractUrlHandlerMapping类 前言 当一个web请求到来时&#xff0c;DispatcherServlet负责接收请求并响应结果。DispatcherServlet首先需要找到当前请求对…

如何创建简单的 Chef Cookbooks 来管理 Ubuntu 上的基础设施

简介 Chef 是一个配置管理系统&#xff0c;旨在让您能够以自动化、可靠和可扩展的方式自动化和控制大量计算机。 在之前的教程中&#xff0c;我们已经了解了一些常见的 Chef 术语&#xff0c;并讨论了如何安装 Chef 服务器、工作站和节点&#xff08;使用 Chef 12 或 Chef 11&…

普通人也能创业!轻资产短视频带货项目,引领普通人实现创业梦想

在这个信息爆炸的时代&#xff0c;创业似乎成为了越来越多人的梦想。然而&#xff0c;传统的创业模式 keJ0277 往往伴随着高昂的资金投入和复杂的管理流程&#xff0c;让许多普通人望而却步。然而&#xff0c;现在有一种轻资产短视频带货项目正在悄然兴起&#xff0c;它以其低…

2024做安全测试必须要知道的几种方法!

前言 安全性测试(Security Testing)是指有关验证应用程序的安全等级和识别潜在安全性缺陷的过程&#xff0c;其主要目的是查找软件自身程序设计中存在的安全隐患&#xff0c;并检查应用程序对非法侵入的防范能力&#xff0c;安全指标不同&#xff0c;测试策略也不同。 但安全…

『Apisix安全篇』快速掌握APISIX Basic-Auth插件高效使用

&#x1f4e3;读完这篇文章里你能收获到 &#x1f468;‍&#x1f4bb; 学习如何快速安装并配置APISIX Basic-Auth插件&#xff0c;为您的API安全保驾护航。&#x1f6e0;️ 文章详细介绍了如何创建带有basic-auth配置的Consumer&#xff0c;以及如何在Route中启用该插件。&am…

微信自主创建表单投票小程序源码系统 带充值刷礼物功能 附带源代码以及完整的安装部署教程

系统概述 本小程序实现的核心功能包括&#xff1a;用户注册登录、表单提交投票、查看投票结果、在线充值以及赠送礼物等。其中&#xff0c;投票表单可以根据实际需求进行自定义设置&#xff0c;满足不同类型的调查或评选活动。同时&#xff0c;通过引入第三方支付接口&#xf…

Expression language groovy is not available.

使用oval校验框架Assert自定义groovy脚本进行内容验证时 Assert(when"groovy:_this.Type R",expr"_value F || _value S" , lang"groovy",message"参数错误") 提示错误&#xff1a; Expression language groovy is n…

Django Celery 的配置及使用---最详细教程

Django Celery 的配置及使用 Redis提供队列消息功能 一、安装redis 系统版本&#xff1a;Ubuntu 20.041、获取最新软件包 sudo apt update sudo apt install redis-server2、安装完成后&#xff0c;Redis服务器会自动启动。查看redis是否启动成功 sudo systemctl status …

LLM大模型多模态面试题(二)

1. 介绍transformer算法 Transformer本身是一个典型的encoder-decoder模型&#xff0c;Encoder端和Decoder端均有6个Block&#xff0c;Encoder端的Block包括两个模块&#xff0c;多头self-attention模块以及一个前馈神经网络模块&#xff1b;Decoder端的Block包括三个模块&…

第九届“数维杯”大学生数学建模挑战赛(B题)深度剖析|建模完整过程+详细思路+代码全解析

问题1 首先&#xff0c;我们需要建立一个数学模型来计算热解产率&#xff0c;该模型为&#xff1a; Y m p m 0 100 % Y \frac{m_p}{m_0} \times 100\% Ym0​mp​​100% 其中&#xff0c; Y Y Y为热解产率&#xff0c;单位为 % \% %&#xff1b; m p m_p mp​为产物的质量&…

多态和多态性

【一】什么是多态 多态是指一个事物的多种形态 【二】示例 例如动物类中有猫类、狗类、猪类 import abc ​ ​ # 总类 动物类 class Animal(metaclassabc.ABCMeta):abc.abstractmethoddef talk(self):pass ​ ​ # 具体类 猫类 class Cat(Animal):def talk(self):print(f&q…

uniapp 实现下拉刷新 下滑更新

效果图 在app或者小程序中向下滑动 会出现刷新数据 ,而上拉到底 需要更新数据 功能实现 主要俩种方式 依赖生命周期 在page.json中开启 page.json "style" : {"navigationBarTitleText" : "小小练习","backgroundTextStyle": &qu…

狙击策略专用术语以及含义,WeTrade3秒讲解

想必各位交易高手对狙击策略不会陌生吧!但你想必不知道狙击策略的开发者为了推广狙击策略&#xff0c;在狙击策略基础的经典技术分析理论引入了自己的术语。今天WeTrade众汇和各位投资者继续了解狙击策略专用术语以及含义。 一.BL 银行级别(BL)是前一日线收盘的级别。时间是格…

微信小程序开发中怎么配置SSL证书?

在微信小程序开发中&#xff0c;配置SSL证书主要用于实现HTTPS请求&#xff0c;以保证数据传输的安全性。以下是配置SSL证书的基本步骤&#xff1a; 一、获取SSL证书 首先&#xff0c;你需要获取一个有效的SSL证书。SSL证书可以被广泛信任的证书颁发机构申请&#xff0c;如Jo…

【GoLang基础】Go常用字符串函数详解

Go 语言提供了一系列强大的字符串处理函数。这些函数主要集中在 strings 和 strconv 包中。下面是一些常用的字符串函数及其详解。 1. strings 包 1.1. Contains 检查字符串是否包含子串。 import ("fmt""strings" )func main() {str "hello wor…

rocketmq的顺序消息开发注意事项

1. 参考消息重试&#xff0c;要对 MaxReconsumeTimes进行设置。之前就是因为没有进行设置&#xff0c;导致了队头阻塞问题。 rokcetmq和kafka一样&#xff0c;当顺序消息写入的多个队列中后&#xff0c;如果是顺序消息&#xff0c;当前的队列的队头一直消费失败的时候&#x…

“分块”算法的基本要素及 build() 函数的构建细节

【“分块”算法知识点】 ● 分块是用线段树的分区思想改良的暴力法。代码比线段树简单。效率比普通暴力法高。分块适合求解 m=n=10^5 规模的问题,或 m*sqrt(n)≈10^7 的问题。其中,n 为元素个数,m 为操作次数。 ● “分块”算法的基本要素 (1)块的大小用 block 表示。通常…

JVM运行时内存:本地方法接口与本地方法栈

文章目录 1. 什么是本地方法&#xff1f;2. 为什么要使用Native Method&#xff1f;3. 本地方法现状 运行时内存整体结构如下图所示: 1. 什么是本地方法&#xff1f; 简单地讲&#xff0c;一个Native Method就是一个Java调用非 Java 代码的接口。一个Native Method是这样一个 …