Рубрики

Напишите свои собственные memcpy () и memmove ()

Функция memcpy используется для копирования блока данных с адреса источника на адрес назначения. Ниже приведен его прототип.

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

Идея состоит в том, чтобы просто ввести указанные адреса в char * (char занимает 1 байт). Затем по одному скопируйте данные из источника в место назначения. Ниже приведена реализация этой идеи.

// Реализация АЦ тетсра ()
#include<stdio.h>
#include<string.h>

  

void myMemCpy(void *dest, void *src, size_t n)

{

   // Typecast src и dest обращаются к (char *)

   char *csrc = (char *)src;

   char *cdest = (char *)dest;

  

   // Копировать содержимое ЦСИ [] Цел []

   for (int i=0; i<n; i++)

       cdest[i] = csrc[i];

}

  
// Драйвер программы

int main()

{

   char csrc[] = "GeeksforGeeks";

   char cdest[100];

   myMemCpy(cdest, csrc, strlen(csrc)+1);

   printf("Copied string is %s", cdest);

  

   int isrc[] = {10, 20, 30, 40, 50};

   int n = sizeof(isrc)/sizeof(isrc[0]);

   int idest[n], i;

   myMemCpy(idest, isrc,  sizeof(isrc));

   printf("\nCopied array is ");

   for (i=0; i<n; i++)

     printf("%d ", idest[i]);

   return 0;

}

Выход:

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

Что такое memmove () ?

memmove () похож на memcpy (), поскольку он также копирует данные из источника в место назначения. memcpy () приводит к проблемам, когда адреса источника и назначения перекрываются, так как memcpy () просто копирует данные по одному из одного места в другое. Например рассмотрим ниже программу.

// Пример программы, показывающей, что memcpy () может терять данные.
#include <stdio.h>
#include <string.h>

int main()

{

   char csrc[100] = "Geeksfor";

   memcpy(csrc+5, csrc, strlen(csrc)+1);

   printf("%s", csrc);

   return 0;

}

Выход:

GeeksGeeksfor

Поскольку входные адреса перекрываются, вышеуказанная программа перезаписывает исходную строку и вызывает потерю данных.

// Пример программы, показывающей, что memmove () лучше чем memcpy ()
// когда адреса перекрываются.
#include <stdio.h>
#include <string.h>

int main()

{

   char csrc[100] = "Geeksfor";

   memmove(csrc+5, csrc, strlen(csrc)+1);

   printf("%s", csrc);

   return 0;

}

Выход:

GeeksGeeksfor

Как реализовать memmove ()?

Хитрость здесь в том, чтобы использовать временный массив вместо прямого копирования из src в dest. Использование временного массива важно для обработки случаев, когда адреса источника и назначения перекрываются.

// C ++ программа для демонстрации реализации memmove ()
#include<stdio.h>
#include<string.h>

  
// Функция для копирования блока из 'n' байтов из источника
// адрес 'src' к адресу назначения 'dest'.

void myMemMove(void *dest, void *src, size_t n)

{

   // Typecast src и dest обращаются к (char *)

   char *csrc = (char *)src;

   char *cdest = (char *)dest;

  

   // Создать временный массив для хранения данных src

   char *temp = new char[n];

  

   // Копируем данные из csrc [] в temp []

   for (int i=0; i<n; i++)

       temp[i] = csrc[i];

  

   // Копирование данных из температуры [] для cdest []

   for (int i=0; i<n; i++)

       cdest[i] = temp[i];

  

   delete [] temp;

}

  
// Драйвер программы

int main()

{

   char csrc[100] = "Geeksfor";

   myMemMove(csrc+5, csrc, strlen(csrc)+1);

   printf("%s", csrc);

   return 0;

}

Выход:

GeeksGeeksfor

Оптимизации:
Алгоритм неэффективен (и честно удваивает время, если вы используете временный массив). Двойных копий следует избегать, если только это действительно невозможно.

В этом случае, однако, можно легко избежать двойных копий, выбрав направление копирования. Фактически это то, что делает библиотечная функция memmove ().

Сравнивая адреса src и dst, вы сможете найти, если они перекрываются.

— Если они не перекрываются, вы можете копировать в любом направлении
— Если они перекрываются, найдите, какой конец dest перекрывается с источником, и соответственно выберите направление копирования.
— Если начало Dest перекрывается, скопируйте с конца на начало
— Если конец Dest перекрывается, скопируйте с начала до конца
— Еще одна оптимизация — копирование по размеру слова. Просто будьте осторожны с граничными условиями.
— Дальнейшая оптимизация будет заключаться в использовании векторных инструкций для копии, поскольку они являются смежными.

Эта статья предоставлена Saurabh Jain. Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Напишите свои собственные memcpy () и memmove ()

0.00 (0%) 0 votes