【问题标题】:Implementing an Optimized Memmove in C [closed]在 C 中实现优化的 Memmove [关闭]
【发布时间】:2021-09-26 19:59:46
【问题描述】:

我正在尝试实现我自己的 memmove 函数。我正在尝试优化它而不是逐字节复制。这是我的实现:

void* my_memmove(void *dest, const void *src, size_t len) {
    
    if((uintptr_t)dest < (uintptr_t)src)
        return memcpy(dest,src,len);
    
    long *pdest = (long*)dest +len;
    const long *psrc = (const long*)src+len;
    
    if(!((uintptr_t)dest+len & (sizeof(long)-1)) &&
      !((uintptr_t)src+len & (sizeof(long)-1))) {
        
        while(len >= sizeof(long)) {
            *--pdest = *--psrc;
            len-=sizeof(long);
        }
    }
    
    char *pdest2 = (char*)pdest;
    const char *psrc2= (const char*)psrc;
    
    while(len) {
        *--pdest2 = *--psrc2;
        len--;
    }
    
    return dest;
}

关于如何改进或现有代码是否存在问题的任何意见?

【问题讨论】:

  • 几率是memmove 已经这样做并处理对齐等。如果您正在寻找您想要的工作代码的评论codereview.stackexchange.com
  • 您需要确保长指针具有正确对齐的地址,即。 e.如果需要分别复制与此类地址不匹配的第一个和最后几个字节,仍然逐字节复制。
  • @RetiredNinja 谢谢!这正是我正在寻找的,将其移至其他论坛。
  • @Aconcagua 谢谢你的回复。为了处理这种情况,我必须先将未对齐的字节复制到字节,然后默认为字复制?
  • 我投票结束这个问题,因为代码审查请求属于代码审查。但请务必阅读their guidelines

标签: c kernel memmove


【解决方案1】:

调用memcpy的代码中有一个错误。

我修改了你的代码

void* my_memmove(void *dest, const void *src, size_t len) {
    
    if((uintptr_t)dest < (uintptr_t)src)
    {
        printf("memcpy\n");
        return memcpy(dest,src,len);
    }
    
    printf("my code\n");
    return NULL;
}

int main() 
{
   unsigned char a[100] = {0};
   my_memmove(&a[0], &a[25], 50);  // Overlapping dst and src
   return 0;
}

输出:

memcpy

所以你用重叠区域调用memcpy

另一个错误...

你对这行有什么期望:

long *pdest = (long*)dest +len;

假设 dest 是 0x1000 并且 len 是 1。您似乎期望值 0x1001 但试试这个:

int main() 
{
    size_t len = 1;
    long *pdest = (long*)0x1000 +len;
    printf("%p\n", (void*)pdest);
    
   return 0;
}

我的系统上的输出:

0x1008

这不是你想要的。

【讨论】:

  • 好点 - 还有更多问题,请参阅 cmets 来提问...
  • @Aconcagua 几个问题...违反严格别名。可能的对齐冲突。地址计算错误。
  • @4386427 感谢您的意见,我知道我需要处理提到的几个问题。我将进行建议的更改并将其发布在代码审查页面上。非常感谢您的帮助!
猜你喜欢
  • 2011-04-04
  • 2021-03-03
  • 2013-11-05
  • 2021-01-20
  • 1970-01-01
  • 2014-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多