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

📅  最后修改于: 2021-05-30 17:00:37             🧑  作者: Mango

memcpy函数用于将数据块从源地址复制到目标地址。以下是其原型。

void * memcpy(void * destination, const void * source, size_t num);

这个想法是简单地将给定的地址类型转换为char *(char需要1个字节)。然后从源到目标一一复制数据。以下是此想法的实现。

// A C implementation of memcpy()
#include
#include
  
void myMemCpy(void *dest, void *src, size_t n)
{
   // Typecast src and dest addresses to (char *)
   char *csrc = (char *)src;
   char *cdest = (char *)dest;
  
   // Copy contents of src[] to dest[]
   for (int i=0; i

输出:

Copied string is GeeksforGeeks
Copied array is 10 20 30 40 50

什么是memmove()?

memmove()与memcpy()类似,因为它还将数据从源复制到目标。当源地址和目标地址重叠时,memcpy()会导致问题,因为memcpy()只是简单地将数据从一个位置一个位置复制到另一个位置。例如考虑下面的程序。

// Sample program to show that memcpy() can loose data.
#include 
#include 
int main()
{
   char csrc[100] = "Geeksfor";
   memcpy(csrc+5, csrc, strlen(csrc)+1);
   printf("%s", csrc);
   return 0;
}

输出:

GeeksGeeksfor

由于输入地址重叠,因此上述程序将覆盖原始字符串并导致数据丢失。

// Sample program to show that memmove() is better than memcpy()
// when addresses overlap.
#include 
#include 
int main()
{
   char csrc[100] = "Geeksfor";
   memmove(csrc+5, csrc, strlen(csrc)+1);
   printf("%s", csrc);
   return 0;
}

输出:

GeeksGeeksfor

如何实现memmove()?

这里的技巧是使用临时数组,而不是直接从src复制到dest。临时数组的使用对于处理源地址和目标地址重叠的情况很重要。

//C++ program to demonstrate implementation of memmove()
#include
#include
  
// A function to copy block of 'n' bytes from source
// address 'src' to destination address 'dest'.
void myMemMove(void *dest, void *src, size_t n)
{
   // Typecast src and dest addresses to (char *)
   char *csrc = (char *)src;
   char *cdest = (char *)dest;
  
   // Create a temporary array to hold data of src
   char *temp = new char[n];
  
   // Copy data from csrc[] to temp[]
   for (int i=0; i

输出:

GeeksGeeksfor

优化:
该算法效率低下(如果使用临时数组,则时间实际上会翻倍)。除非确实不可能,否则应避免重复副本。

在这种情况下,尽管很容易通过选择复印方向来避免重复复印。实际上,这就是memmove()库函数的作用。

通过比较src和dst地址,您应该能够找到它们是否重叠。

–如果它们不重叠,则可以向任何方向复制
–如果它们确实重叠,请找到目标的哪一端与源重叠,并相应地选择复制方向。
–如果dest的开头重叠,请从末尾开始复制
–如果dest的末尾重叠,请从头到尾复制
–另一个优化是按字号进行复制。请小心处理边界条件。
–进一步的优化将是使用矢量指令作为副本,因为它们是连续的。

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”