为什么memmove会先填充几个字节

时间:2016-02-08 13:00:24

标签: c memory memcpy

我正在写一个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个字节是乱码。其余部分按预期复制。

导致此行为的原因是什么?

2 个答案:

答案 0 :(得分:3)

  1. 以下是UB。无法可靠地与不属于同一数组的< <= >= > 2个指针进行比较。

    if(s < d && s + n > d){
    
  2.   

    当比较两个指针时,结果取决于指向的对象的地址空间中的相对位置。如果指向对象类型的两个指针都指向同一个对象,...如果指向的对象是同一个聚合对象的成员,则...指向同一个union对象的成员的所有指针... 在所有其他对象中情况,行为未定义。
      C11dr§6.5.85关系运算符

    1. 使用size_t n而不是uint32_t n更为规范。

    2. 在以下用法中,dest, src均未初始化@Bathsheba delted answer。根据用户信息,似乎代码试图写入地址0.可能系统会阻止它。但是使用未初始化的指针是UB。

      char *dest
      char *origin    
      memmove(dest, origin, 100);
      

答案 1 :(得分:0)

原来memmove成功没有错误,但并发(错误)进程正在颠倒前4个字节。我应该更好地测试一下。

感谢您的所有答案。