【日志记录】---编译器内存对齐优化导致结构体指针引用成员出现地址错位

一:问题现象

在一个跨线程数据处理消息的时候出现了以下内存错位现象,在结构体指针引用的时候出现了成员数据异常

1.【数据源】线程A消息里面赋值的数据

//字节流
message.data[0] = (unsigned char)model_brake_disable_type_read();
message.data[1] = (unsigned char)(temp & 0xff);
message.data[2] = (unsigned char)((temp >> 8) & 0xff);

2.【目标结构体】线程B知道线程A该条消息的结构体,定义了专门的结构体来套字节流中的数据 

typedef struct    //目标结构体
{unsigned char break_disable_type;unsigned short break_disable_time;
}break_disable_info_t;

3.【问题出现】线程B通过直接打印和结构体成员引用的方式分别输出内容,发现结构体第二个成员输出内容异常❌

//套结构体体指针,以成员的形式引用data内容
break_disable_info_t *disableFrame = (break_disable_info_t *)message->data;printf("[pad] type%d\r\n", message->data[0]);    //输出1,正确
printf("[pad] time%d\r\n", (*((short*)(message->data+1))));    //输出60,正确printf("[pad] type%d\r\n", disableFrame->break_disable_type);    //输出1,正确
printf("[pad] time%d\r\n", disableFrame->break_disable_time);    //输出0,错误

4.【反复调试】卡这里一直想不通,语法各方面都不存在问题,一直调试打印成员变量地址,结构体和成员大小发现了异常地方

发现两个结构体成员并不连续,中间出现了一个空位

进一步调试发现原本3个字节大小的结构体,在内存中占用了四个字节的位置,这正是导致输出数据异常的原因,多出的一个字节导致数据引用出现了错位

printf("[pad] p:%p, size:%d\r\n", disableFrame_p, sizeof(break_disable_info_t_));

二:原因解析

起初反复检查,查看之前代码也是这样处理的,没有任何问题,反复调试差点放弃打算换一种写法放过这个问题,最终还是比较犟,经过上面一顿懵逼和调试后,怀疑可能是编译器内存优化,找了一下资料得到一下结论:

在C语言中,struct的大小通常取决于其成员的类型、数量以及可能的内存对齐(padding)。当你定义了如下的结构体:

typedef struct  
{  char break_disable_type;  unsigned short break_disable_time;  
} break_disable_info_t_;

char类型通常占用1个字节,而unsigned short类型在大多数现代系统上占用2个字节。但是,由于数据对齐的需要,编译器可能会在char成员后面插入填充字节(padding),以确保unsigned short从适当的地址开始。

数据对齐是许多系统为了提高访问性能而采取的一种策略。对于某些处理器,从一个对齐的地址读取或写入数据比从一个未对齐的地址更快。此外,一些处理器甚至无法从未对齐的地址访问数据,或者这样做会导致硬件异常。

在你的例子中,char后面可能有一个填充字节,以确保unsigned short从2的倍数地址开始(这取决于编译器的具体实现和平台的对齐要求)。因此,整个结构体的大小可能是:

  • char:1字节
  • 填充(padding):1字节(为了对齐unsigned short
  • unsigned short:2字节

总共 4 字节。

你可以通过sizeof运算符来检查结构体的大小,如下所示:

#include <stdio.h>  typedef struct  
{  char break_disable_type;  unsigned short break_disable_time;  
} break_disable_info_t_;  int main() {  printf("Size of break_disable_info_t_: %zu bytes\n", sizeof(break_disable_info_t_));  return 0;  
}

如果你在输出中看到4,那么说明编译器确实在charunsigned short之间插入了一个填充字节。如果你想要避免这种填充(在某些情况下,比如内存使用非常关键时),你可以使用特定的编译器指令或属性来控制对齐,但这通常不是推荐的做法,除非你有明确的理由。

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

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

相关文章

【C++】C++11--- 类的新功能

目录 类的新功能 默认成员函数 示例 类成员变量初始化 强制生成默认函数的关键字default 禁止生成默认函数的关键字delete 类的新功能 默认成员函数 构造函数析构函数拷贝构造函数拷贝赋值重载取地址重载const取地址重载 C11在原先的6个默认成员函数的基础上&#xff0c…

OceanBase学习1:分布式数据库与集中式数据库的差异

目录 1. 传统集中式数据库 2. 数据库中间件的分库分表 3. 分布式数据库的基本特点及对比分析 4. OceanBase和传统数据库的对比 5. 小结 1. 传统集中式数据库 优点 成熟稳定:经过近40年的发展&#xff0c;应用到各行各业&#xff0c;产品技术非常成熟稳定行业适配性强:适配…

RabbitMQ的介绍和使用

1.同步通讯和异步通讯 举个例子&#xff0c;同步通讯就像是在打电话&#xff0c;因此它时效性较强&#xff0c;可以立即得到结果&#xff0c;但如果你正在和一个MM打电话&#xff0c;其他MM找你的话&#xff0c;你们之间是不能进行消息的传递和响应的 异步通讯就像是微信&#…

流畅的python-学习笔记_一等函数

函数对象 函数也是对象&#xff0c;操作可像对象一般操作 高阶函数 高阶函数指接受参数为函数&#xff0c;或返回函数的函数 不少高阶函数在py3已经有了替代品。map&#xff0c; filter可通过生成式实现&#xff0c;reduce&#xff08;在functools里&#xff09;可通过sum实…

解决 git克隆拉取代码报SSL certificate problem错误

问题&#xff1a;拉取代码时报错&#xff0c;SSL证书问题:证书链中的自签名证书问题 解决&#xff1a;只需要关闭证书验证&#xff0c;执行下面代码即可&#xff1a; git config --global http.sslVerify "false" 再次拉取代码就可以了

使用代理IP时,如何预防未知的风险?

在使用代理IP时&#xff0c;预防未知的风险是至关重要的。代理IP虽然提供了诸多便利&#xff0c;如匿名浏览、访问控制和内容过滤等&#xff0c;但如果不加以妥善管理和使用&#xff0c;可能会面临数据泄露、隐私暴露、恶意活动关联等风险。以下是一些建议&#xff0c;以帮助您…

使用mxnet中的img2rec.py制作rec数据集

源码链接&#xff1a;mxnet/tools/im2rec.py at master apache/mxnet GitHub 重点关注入参函数即可&#xff0c; def parse_args():"""Defines all arguments.Returns-------args object that contains all the params"""parser argparse.A…

一键实现在VS Code中绘制流程图

VS Code是一款常用的IDE&#xff0c;受到许多用户的欢迎和喜爱。而其较为出众的一点&#xff0c;就是较好的可拓展性&#xff0c;即丰富的插件应用&#xff0c;这些应用可以极大地提高生产效率&#xff0c;并优化日常使用。 流程图是一种直观的图示方法&#xff0c;可以用简明…

BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU、TCN-BIGRU-ATTENTION合集

&#xff08;BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU、TCN-BIGRU-ATTENTION&#xff09;时&#xff0c;我们可以从它们的基本结构、工作原理、应用场景以及优缺点等方面进行详细介绍和分析。 BIGRU、CNN-BIGRU、CNN-BIGRU-ATTENTION、TCN-BIGRU等&#xff08;matlab…

层级实例化静态网格体组件:开启大量模型处理之门

前言 在数字孪生的世界里&#xff0c;我们常常需要构建大量的模型来呈现真实而丰富的场景。然而&#xff0c;当使用静态网格体 &#xff08;StaticMesh &#xff09;构建大量模型时&#xff0c;可能会遇到卡顿的问题&#xff0c;这给我们带来了不小的困扰&#x1f623;。那么&…

Spring Data JPA自定义Id生成策略、复合主键配置、Auditing使用

前言 在Spring Data JPA系列的第一篇文章 SpringBoot集成JPA及基本使用-CSDN博客 中讲解了实体类的Id生成策略可以通过GeneratedValue注解进行配置&#xff0c;该注解的strategy为GenerationType类型&#xff0c;GenerationType为枚举类&#xff0c;支持四种Id的生成策略&…

STM32F407VET6 学习笔记2:定时器、串口、自定义串口打印函数

今日继续学习使用嘉立创购买的 立创梁山派天空星&#xff0c;芯片是 STM32F407VET6 因为已经有学习基础了&#xff0c;所以学习进度十分快&#xff0c;这次也是直接一块学习配置定时器与串口了&#xff0c;文章也愈来愈对基础的解释越来越少了...... 文章提供测试代码讲解、完…

【如此简单!数据库入门系列】之思想地图 -- 系列目录

文章目录 1 前言2 基本概念3 基本原理4 数据库历史5 数据模型6 数据库规范化7 数据存储8 总结 1 前言 目录是思想地图&#xff0c;指引我们穿越文字的森林。 为了方便系统性阅读&#xff0c;将【如此简单&#xff01;数据库入门系列】按照模块划分了目录结构。 2 基本概念 【…

Jetpack Compose(一

Intellij IDEA构建Android开发环境 IntelliJ IDEA 2023.2.1 Android开发变化 IDEA配置使用Gradle 新建Compose工程&#xff0c;取名ComposeStudy 可以看到的是IDEA为项目初始化了部分代码 使用Compose开发不再需要使用xml文件来设计布局了 Compose中的Text也不同于Android V…

ogv转mp4怎么转?只需3个步骤~

OGV&#xff08;Ogg Video&#xff09;是一种开源的视频文件格式&#xff0c;起源于对数字媒体领域的开放标准的需求。作为Ogg多媒体容器的一部分&#xff0c;OGV的设计初衷是提供一种自由、高质量的视频编码方案&#xff0c;以满足多样化的应用需求。 支持打开MP4文件格式的软…

119. 再谈接口幂等性

文章目录 0. 前言1. insert前先select2. 加悲观锁3. 加乐观锁5. 加唯一索引【配合 &#xff08;1. insert前先select &#xff09;最常用 】6. 建防重表6. 根据状态机7. 加分布式锁8. 获取token 0. 前言 在 93. 通用防重幂等设计 一文中&#xff0c;已经介绍过幂等的使用。该文…

【一看就懂】UART、IIC、SPI、CAN四种通讯协议对比介绍

UART、IIC、SPI、CAN四种通信协议对比 通信方式传输线通讯方式标准传输速度使用场景UARTTX(发送数据线)、RX(接收数据线)串行、异步、全双工115.2 kbit/s(常用)计算机和外部设备通信&#xff08;打印机&#xff09;IICSCL(时钟线)、SDA(数据线)串行、同步、半双工100 kbit/s(标…

一种由RSOA和PIC集成的宽可调激光器

----翻译自Nouman Zia, Samu-Pekka Ojanen, Jukka Viheriala, Eero Koivusalo, Joonas Hilska, Heidi Tuorila, and Mircea Guina在optics letter上发的文章vol.48, Issue 5, pp. 1319-1322(2023) 摘要&#xff1a;通过光子集成方式实现的2-3μm波长的可调激光器&#xff0c;在…

Adobe Acrobat Pro DC 2022一款高效强大的PDF阅读编辑专业软件(240506)

01 软件介绍 Adobe Acrobat Pro DC 2022&#xff0c;作为一款专业的PDF处理工具&#xff0c;它集成了强大的制作功能&#xff0c;能够与Adobe Photoshop的高级图像编辑能力无缝衔接&#xff0c;进而将各类纸质文档高效转换成可编辑的电子格式&#xff0c;以便于文件的传输和签…

跨越语言界限,多语言盲盒小程序带你领略全球风情

在全球化的今天&#xff0c;我们生活在一个多元文化的世界中&#xff0c;不同的语言、风俗、习惯共同构成了这个五彩斑斓的地球村。为了让每个人都能轻松体验到世界各地的独特风情&#xff0c;一款创新的多语言盲盒小程序应运而生&#xff0c;它跨越了语言的界限&#xff0c;让…