📜  编写自己的memcpy()和memmove()(1)

📅  最后修改于: 2023-12-03 15:41:19.410000             🧑  作者: Mango

编写自己的memcpy()和memmove()

在C/C++语言中,memcpy()memmove()是非常常用、且有用的库函数。它们的功能都是将一片内存区域中的数据复制到另一片内存区域中,区别是memcpy()是直接进行复制,如果两片区域有重叠部分,就会出现错误,而memmove()则是一片一片地移动数据,可以处理重叠的部分。

这篇文章将介绍如何编写自己的memcpy()memmove()函数,并通过代码实现展示。

编写自己的memcpy()

在编写自己的memcpy()函数时,需要考虑如下问题:

  • 内存区域可能有重叠部分,必须判断
  • 如何提高复制效率

我们可以通过指针运算来实现相应功能。具体操作可以看以下代码实现:

#include <iostream>
#include <cstring>

void* my_memcpy(void* dst, const void* src, size_t num) {
    std::cout << "my_memcpy: copying " << num << " bytes\n";
    char* c_dst = (char*)dst;
    const char* c_src = (const char*)src;
    if(c_dst <= c_src || c_dst >= c_src + num) { // 不重叠时
        while(num--)
            *c_dst++ = *c_src++;
    }
    else { // 有重叠时
        c_dst += num - 1;
        c_src += num - 1;
        while(num--)
            *c_dst-- = *c_src--;
    }
    return dst;
}

int main() {
    char dst[20], src[20];
    std::strcpy(src, "Hello");
    my_memcpy(dst, src, 6);
    std::cout << dst << std::endl;
    return 0;
}

上述代码中,my_memcpy()函数通过指针来访问相应内存地址,并使用了分别从前向后和从后向前复制的方法。输出如下:

my_memcpy: copying 6 bytes
Hello
编写自己的memmove()

在编写自己的memmove()函数时,需要考虑如下问题:

  • 内存区域可能有重叠部分,必须判断
  • 如何提高复制效率

同样我们可以通过指针运算来实现相应功能。具体操作可以看以下代码实现:

#include <iostream>
#include <cstring>

void* my_memmove(void* dst, const void* src, size_t num) {
    std::cout << "my_memmove: copying " << num << " bytes\n";
    char* c_dst = (char*)dst;
    const char* c_src = (const char*)src;
    if(c_dst <= c_src || c_dst >= c_src + num) { // 不重叠时
        while(num--)
            *c_dst++ = *c_src++;
    }
    else { // 有重叠时
        c_dst += num - 1;
        c_src += num - 1;
        while(num--)
            *c_dst-- = *c_src--;
    }
    return dst;
}

int main() {
    char s[] = "Hello";
    my_memmove(s+2, s, 6);
    std::cout << s << std::endl;
    return 0;
}

上述代码中,my_memmove()函数与my_memcpy()函数相同,只是不同的调用方式。输出如下:

my_memmove: copying 6 bytes
HeHello
总结

在C/C++语言中,memcpy()memmove()函数非常常用、且有用。了解它们的实现原理,对深入理解其使用非常有益。本文通过代码实现,展示了如何编写自己的memcpy()memmove()函数。阅读完本文后,读者应该能够更好地掌握这两个函数,轻松理解相应程序。