Memcpy vs Memmove

The C standard library (stdlib) facilitates two functions for copying memory regions, they are memcpy and memmove. We often wonder -

  • Why memmove is there when memcpy is already there?
  • Is memmove different from memcpy?
  • When should we use memmove over memcpy?
Both the functions copy a chunk of memory bytes from a source location to a destination location. However, the important difference is that memcpy does not behave correctly when dealing with overlapping regions. Let us study these functions with examples and then try to understand the overlapping source and destination case.

Memcpy referance

NAME
     memcpy - copy area of memory bytes from source to destination.

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <string.h>

     void *
     memcpy(void * dst, const void * src, size_t n);

DESCRIPTION
     The memcpy() function copies n bytes from memory from src location to
     memory pointed to dst.  If dst and src area overlaps then behavior is
     undefined. Applications which might deal with dst and src might overlap should use memmove(3) instead.

RETURN VALUE
     The memcpy() function returns the original value of dst.

Memcpy

memcpy() is generally used to copy a portion of memory chuck from one location to another location. memcpy() works fine when there is no overlapping between source and destination. Lets consider a overlapping of buffer in the front side/lower side. Below picture shows the details.

memcpy() where overlapping in lower side of memory

Memcpy implementation in C

void memcpy(void *dest, void *src, int size)
{
  int i;
  for (= 0; i < size; i++)
  {
    ((char *)dest)[i] = ((char *)src)[i];
  }
}

void print_elements(char *array, int size)
{
  int i;
  printf ("Elements : ");
  for (= 0; i < size; i++) {
    printf ("%c, ", array[i]);
  }
  printf ("\n");
}
int main(int argc, char* argv[])
{
  char c_array[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  print_elements(c_array, sizeof(c_array));
  printf("After memcpy()\n");
  memcpy((void *)&c_array[1], (void *)&c_array[3], 5);
  print_elements(c_array, sizeof(c_array));
}

Output
Elements : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
After memcpy()
Elements : 0, 3, 4, 5, 6, 7, 6, 7, 8, 9,

However memcpy() works fine here. Now consider a case where overlapping is there at the trailing side or in upper side of the memory.

memcpy() where overlapping in upper side of memory

void memcpy(void *dest, void *src, int size)
{
  int i;
  for (= 0; i < size; i++)
  {
    ((char *)dest)[i] = ((char *)src)[i];
  }
}

void print_elements(char *array, int size)
{
  int i;
  printf ("Elements : ");
  for (= 0; i < size; i++) {
    printf ("%c, ", array[i]);
  }
  printf (" ");
}
int main(int argc, char* argv[])
{
  char c_array[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  print_elements(c_array, sizeof(c_array));
  printf("After memcpy()\n");
  memcpy((void *)&c_array[5], (void *)&c_array[3], 5);
  print_elements(c_array, sizeof(c_array));
}

Output
Elements : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
After memcpy()
Elements : 0, 1, 2, 3, 4, 3, 4, 3, 4, 3,

Here result is not expected. From the above graphical view it is clear that some mechanism should be there to take care of the overlapping and displacement of elements should be in the reverse direction when overlapping is at the trailing side. Below diagram shows how it should be.

memmove() where overlapping in upper side of memory

Memmove referance

NAME
     memmove - copies bytes from source to destination
               while taking care of overlapping.

LIBRARY
     Standard C Library (libc, -lc)

SYNOPSIS
     #include <string.h>

     void *
     memmove(void *dst, const void *src, size_t n);

DESCRIPTION
     The memmove() function copies n bytes from src area to dst area.
     These two areas might overlap; the copy process always done in a non-destructive
     manner.

RETURN VALUES
     The memmove() function returns the original value of dst.

Memmove

Memmove copies memory blocks from source location to destination location like memcpy but it also takes care of the overlapping. Copy of the memory bytes are done in non-destructive manner.

Memmove implementation in C

void memmove(void *dest, void *src, int size)
{
  int i;
  if (dest < src) {
    for (= 0; i < size; i++) {
      ((char *)dest)[i] = ((char *)src)[i];
    }
  } else {
    for (= size - 1; i >= 0; i--) {
      ((char *)dest)[i] = ((char *)src)[i];
    }
  }
}
int main(int argc, char* argv[])
{
  char c_array[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  print_elements(c_array, sizeof(c_array));
  printf("After memmove()\n");
  memcpy((void *)&c_array[5], (void *)&c_array[3], 5);
  print_elements(c_array, sizeof(c_array));
}

Output
Elements : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
After memmove()
Elements : 0, 1, 2, 3, 4, 3, 4, 5, 6, 7,

About our authors: Team EQA

You have viewed 1 page out of 252. Your C learning is 0.00% complete. Login to check your learning progress.

Further readings

Construct your own strcpy and strcat/implementation of strcpy, strcat function in C
strcpy, strcat implementation in c using pointers, strncpy, strcat implementation in c, strcmp, strcat implementation in c, strcat implementation in c, implementation of strcpy, strcat function in c

How strrev() works? Explain working principle with source code.
Explain implementation details of strrev. Explain working principle of strrev with source code. Shows how to swap characters with diagram

How to duplicate a string? (String duplication with strdup)
How to duplicate a string? (String duplication with strdup)

How to split/tokenize a string? (strtok() string tokenizer)
How to split/tokenize a string? (strtok() string tokenizer)

#