我正在写一个hobbyOS。我想将一小段内存从1个地方复制到另一个地方。不知怎的,我的memmove
函数不断地填充前几个字节,只剩下前几个字节。
这是我的memmove功能:
void* memmove(void *dst, const void *src, uint32_t n)
{
const char *s;
char *d;
s = src;
d = dst;
if(s < d && s + n > d){
s += n;
d += n;
while(n-- > 0)
*--d = *--s;
} else
while(n-- > 0)
*d++ = *s++;
return dst;
}
然后我按照这样调用函数:
char *dest
char *origin
memmove(dest, origin, 100);
当我(我正在使用Boschs)之后检查内存时,我在前几个字节中得到这个奇怪的差异,之后的所有内容都按预期复制:
original at 0x502220:
0x0000000000502220 <bogus+ 0>: 0x50224468 0x223c6800 0x006a0050
copy at 0x0:
0x0000000000000000 <bogus+ 0>: 0x00504460 0x223c6800 0x006a0050
如您所见,只有前4个字节是乱码。其余部分按预期复制。
导致此行为的原因是什么?
答案 0 :(得分:3)
以下是UB。无法可靠地与不属于同一数组的< <= >= >
2个指针进行比较。
if(s < d && s + n > d){
当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果指向对象类型的两个指针都指向同一个对象,...如果指向的对象是同一个聚合对象的成员,则...指向同一个union对象的成员的所有指针... 在所有其他对象中情况,行为未定义。
C11dr§6.5.85关系运算符
使用size_t n
而不是uint32_t n
更为规范。
在以下用法中,dest, src
均未初始化@Bathsheba delted answer。根据用户信息,似乎代码试图写入地址0.可能系统会阻止它。但是使用未初始化的指针是UB。
char *dest
char *origin
memmove(dest, origin, 100);
答案 1 :(得分:0)
原来memmove
成功没有错误,但并发(错误)进程正在颠倒前4个字节。我应该更好地测试一下。
感谢您的所有答案。