搜索
bottom↓
回复: 17

请教如何判断两个结构体的元素值是否相同?

[复制链接]

出0入36汤圆

发表于 2021-10-3 13:45:35 | 显示全部楼层 |阅读模式
typedef struct Test
{
    int a;
    char b;
}test;
test  info1,info2;
据说因为字节对齐问题,不能使用memcmp.

只能如下这样一个一个元素去判断是否相同吗?
if(info1.a == info2.a)  
{
}
if(info1.b == info2.b)  
{
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入1119汤圆

发表于 2021-10-3 14:22:24 | 显示全部楼层
都用memset清零初始化再memcmp

出0入0汤圆

发表于 2021-10-3 18:04:02 来自手机 | 显示全部楼层
strstr((char*)&info1,(char*)&info2) == null

出200入2554汤圆

发表于 2021-10-3 18:44:50 | 显示全部楼层
zhd1021 发表于 2021-10-3 18:04
strstr((char*)&info1,(char*)&info2) == null

一般性的数组,拿 str 来比较不废了吗,遇到 0x00 就截断了

出200入2554汤圆

发表于 2021-10-3 18:47:26 | 显示全部楼层
只能一个个比过去,除非确保没有 padding 空白位置,或者空白位置内容可控

出0入475汤圆

发表于 2021-10-3 18:56:07 来自手机 | 显示全部楼层
是不是直接用最原始的办法每个字节今下午比较就好了?编译那个啥选项选择单字节对其啥玩意的,
for(I=0;I<(sizeof 数组);i++)
{if((unsigned char*)&inf1+i != xxxinf2+i

抱歉手机编辑好痛苦,另外没有学过C语言,但是自己摸索过,应该是没什么问题,上面那个if里面那里就是两个内容进行比较,只是比较之前讲结构图转换为单字节的指针形式,可能我转转的写法不对,所以都懒得弄格式了:) 但自己觉得应该是对的,因为之前自己也这样判断过东西,

出200入2554汤圆

发表于 2021-10-3 19:09:12 | 显示全部楼层
1a2b3c 发表于 2021-10-3 18:56
是不是直接用最原始的办法每个字节今下午比较就好了?编译那个啥选项选择单字节对其啥玩意的,
for(I=0;I ...

1字节对齐以后,无论是手动遍历,还是 memcmp 都可以工作,如下图 pack(1) 的情况。

多字节对齐例如 pack(4),会多出很多 pad 空位。
这时无论手动遍历还是 memcmp 都是不安全的,原因在于 pad 数据不可控,会影响比较结果。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入475汤圆

发表于 2021-10-3 19:55:07 来自手机 | 显示全部楼层
t3486784401 发表于 2021-10-3 19:09
1字节对齐以后,无论是手动遍历,还是 memcmp 都可以工作,如下图 pack(1) 的情况。

多字节对齐例如 pac ...

嗯我不懂太高深的东西,对我来说只适合if else :)
不过字节对齐这个坛里好多描述的,所以也大概看懂了,所以也知道要对齐才能我那样处理,自己也验证了没有问题。
但是一说起我了解的之外的知识,对我来说就难了 :)

出350入477汤圆

发表于 2021-10-3 20:33:56 来自手机 | 显示全部楼层
t3486784401 发表于 2021-10-3 19:09
1字节对齐以后,无论是手动遍历,还是 memcmp 都可以工作,如下图 pack(1) 的情况。

多字节对齐例如 pac ...

只要最初第一次是全清零过的,以后所有的padding区都不可能被任何别的操作改变啊,所以你直接用memcmp比较完全可以。

出0入17汤圆

发表于 2021-10-3 21:12:57 | 显示全部楼层
pack1 对于不支持非对齐访问的硬件来说, 访存开销有点大.
如2楼和9楼所说, 用之前保证padding是清0过的, 用的时候保证不碰pedding部分, 用memcmp来比较还是安全的.
不过这对代码质量有更高要求了, 有BUG碰到padding的话, 传播链可能会很长, debug可能要折腾好一会.

出0入42汤圆

发表于 2021-10-3 21:47:37 | 显示全部楼层
如果这种判断不是每秒要进行几十万次几百万次的话,一个一个比最稳妥,逻辑上也是没有疏漏的。

出350入477汤圆

发表于 2021-10-3 22:15:13 来自手机 | 显示全部楼层
Clamfly 发表于 2021-10-3 21:12
pack1 对于不支持非对齐访问的硬件来说, 访存开销有点大.
如2楼和9楼所说, 用之前保证padding是清0过的, 用 ...

如果你结构体里不装字符串,或者说不装任何数组。那么要是能用常规的代码去改变padding区的内容还真算是个人才,哈哈

出0入17汤圆

发表于 2021-10-3 22:21:23 | 显示全部楼层
他山之石:
https://embeddedgurus.com/stack- ... ructure-comparison/

没有超出前面的讨论范围太多, 作者是建议按需求采用不同的做法.
用memcmp还要注意boolean/float/double类型的成员, 这些成员的内存原始值的不同, 不代表成员表义上的值的不同.

出0入663汤圆

发表于 2021-10-3 22:21:32 | 显示全部楼层
不同平台除了padding还要考虑大小端……

出0入17汤圆

发表于 2021-10-3 22:25:30 | 显示全部楼层
本帖最后由 Clamfly 于 2021-10-4 08:08 编辑
redroof 发表于 2021-10-3 22:15
如果你结构体里不装字符串,或者说不装任何数组。那么要是能用常规的代码去改变padding区的内容还真算是 ...


这个struct跟别的struct一起, 放在更外边一层union里, 很容易触发那种BUG的.
这种内存布局在MCU上还是比较常见的, 为了复用内存.

修改原因:缓和语气

出0入0汤圆

发表于 2021-10-3 22:39:05 | 显示全部楼层
一般定义时按4字节对齐,实在有空位也要用null_val填充。不用编译器的自动占位对齐,就没有这么多问题了。

出0入36汤圆

 楼主| 发表于 2021-10-3 23:19:30 来自手机 | 显示全部楼层
本帖最后由 GZZXB 于 2021-10-3 23:22 编辑

感谢各位的回复。认真阅读了楼上各位的回复,觉得还是逐个元素判断来的安心些?

出350入477汤圆

发表于 2021-10-4 08:58:22 来自手机 | 显示全部楼层
flash3g 发表于 2021-10-3 22:39
一般定义时按4字节对齐,实在有空位也要用null_val填充。不用编译器的自动占位对齐,就没有这么多问 ...

这样也没区别。你把padding明着定义岀来,并且保证从不操作它,也不能防止别人把它装到union里去改变那些内容。
除了超岀数组范围以外,唯一可以改变那些padding内容的办法就是外面套个union了。其实union也不是常规代码,它就是强制对内存重解释的。对c++你可以给某个struct定义一个构造函数来防止它被人装到union里。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-16 12:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表