最近的工作中,发现有一个很奇怪的问题,就是两个结构体,里面的字段的值完全是一样的,但是用memcpy就是不返回0。大致是下面的代码:
输出是:aa != bb
bb != cc
为什么设的值都是一样的,但是memcmp就是返回不一样呢。memcpy还算是一个比较常用的函数,特别是在c语言中比较一个有较多字段的结构体,很方便。但是问题往往也就发生在这样的地方。
这里先要看下结构体A,一共是7个字节(以32位平台为例子)。但是编译器会进行字节对齐,我用的是vc2008,我不确定默认字节对齐是什么,用sizeof(A)来查看的话会得到8,好了,也就是说最后一个字节是编译器padding上去的,那这个padding上去的值是多少呢?
可以用下面的代码来看padding的字节的值:
从bb的输出来看padding上去的不是0,而是0xCC。而aa在前面已经用memset设置为0了,所以padding的值也变成0了。
而cc上又变成了0xCD。bb是分配的在栈上的,而cc是通过malloc分配得到的分配在堆上的内存,看来内存方式分配的不同,还会导致padding不同(但是经过测试,发现相同的内存分配方法的话对于同一个结构体内存是一样的)。
再来看memcmp(&aa, &bb, sizeof(A));sizeof(A)=8,所以memcmp会去比较8个长度的字节。所以aa,bb,cc的最后第二个字节(或最后一个字节,取决于内存是小端还是大端的)不同,导致memcmp失败。
从这个例子中可以发现使用memcmp比较特别是结构体的时候还是要十分小心的,最好还是逐个比较字段来的安全,除非你已经比较熟悉编译器的行为。虽然是个小错误,但是却很难发现尤其当程序没有异常结果时,但是却想一颗定时炸弹一样随时会爆炸...



被折叠的 条评论
为什么被折叠?



