【问题标题】:why is memmove garbling first few bytes为什么 memmove 前几个字节乱码
【发布时间】:2016-02-08 13:00:23
【问题描述】:

我正在编写一个 hobbyOS。我想将一小部分内存从一个点复制到另一个点。不知何故,我的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 个字节是乱码。其余部分按预期复制。

是什么导致了这种行为?

【问题讨论】:

  • 你分配内存了吗?
  • 代码看起来不错,与what I wrote for PDCLib 几乎相同,测试正常。 (欢迎您将 PDCLib 部分或整体用于您的爱好操作系统。它就是为此目的而编写的。)我怀疑您的测试有错误,真的。
  • 你真的要搬到地址 0 吗?如果你真的是,也许你有其他东西写入空指针?
  • @ElderBug: 空指针 与地址 0 不同。
  • @Olaf 没有理智的编译器会使空指针不为 0。C 标准要求 (char*)0 转换为空指针。

标签: c memory memcpy


【解决方案1】:
  1. 接下来是UB。无法可靠地与&lt; &lt;= &gt;= &gt; 2 个不属于同一数组、对象的指针进行比较。

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

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

  1. 使用size_t n 比使用uint32_t n 更规范。

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

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

【讨论】:

    【解决方案2】:

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

    感谢您的所有回答。

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 2015-04-21
      • 2012-01-23
      • 2020-01-01
      • 2012-09-02
      • 1970-01-01
      相关资源
      最近更新 更多