Open-Source Internship opportunity by OpenGenus for programmers. Apply now.
In this article, we have explored the differences between the two built-in functions memcpy and memmove of C programming language. Both are part of the C library - <string.h>
. What's so different about both of them ?
Ever came across how to copy a memory block from one location ( memory address ) to another in C. This article at OpenGenus addresses this problem in depth.
Table of contents:
- Introduction
- memcpy
- memmove
- How memmove is different from memcpy?
Following table summarizes the differences between the two built-in functions memcpy and memmove:
Point | memcpy | memmove |
---|---|---|
Built-in function | Yes | Yes |
Purpose | Copies data directly to destination | Copies data to temporary buffer and then, to destination. |
Overflow | Yes, as there is no check for \0 (null terminator) | No overflow as null terminator is considered. |
Overlap | Wrong output when source and destination memory overlap. | No problem as data to first copied to temporary buffer. |
Performance | Faster | Slower than memcpy by nearly 2X |
Recommended to use | Recommended in general | Recommended in cases where source and destination memory can overlap |
Output | May be wrong if source and destination memory can overlap and if there is overflow | Always correct |
Following is a C code snippet using memcpy and memmove:
char message2[60] = "abcdefghijklmnopqrstuvwxyz";
char temp[60];
strcpy(temp, message2);
memcpy(temp + 4, temp + 16, 10);
memmove(temp + 4, temp + 16, 10);
Introduction
If we want to copy a string and get a substring or change the same string, this would get us a better understanding of both functions.
Following is a complete C program demonstrating a basic use of memory operations:
// Part of iq.opengenus.org
// iq.opengenus.org/memcpy-vs-memmove/
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
const char src[50] = "Memcpy vs Memmove";
char dest[50];
memset(dest,'\0',50);
for (int i = 0; i < 6; i++)
{
dest[i] = src[i];
}
printf("%s\n",dest );
return 0;
}
Output:
Memcpy
Undderstand the idea behind memset in depth.
This code above might be for a beginner who's trying to get a substring but we could use C library functions, memcpy and memmove and not use the for loop.
memcpy
Following is the syntax of memcpy built-in function in C:
void *memcpy(void *str1, const void *str2, sizet n)
memcpy() copies n characters from memory area str2 ( source ) to memory area str1 ( destination ).
Parameters of memcpy
- str1 − This is pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.
- str2 − This is pointer to the source of data to be copied, type-casted to a pointer of type void*.
- n − This is the number of bytes to be copied.
Return Value of memcpy
This function returns a pointer to destination, which is str1.
Following C program demonstrates the use of memcpy():
// Part of iq.opengenus.org
// iq.opengenus.org/memcpy-vs-memmove/
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
const char src[50] = "Memcpy vs Memmove";
char dest[50];
memset(dest,'\0',50);
memcpy(dest,src,sizeof(char) * 6);
printf("%s\n",dest );
return 0;
}
Output:
Memcpy
memmove
void *memmove(void *str1, const void *str2, sizet n)
Does this function feel the same as of memcpy? Should the output to the console be same?
// Part of iq.opengenus.org
// iq.opengenus.org/memcpy-vs-memmove/
#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
const char src[50] = "Memcpy vs Memmove";
char dest[50];
memset(dest,'\0',50);
memmove(dest,src,sizeof(char) * 6);
printf("%s\n",dest );
return 0;
}
The output for both memcpy and memmove is the same. Did they make an error? Duplicate function? No not really, we will look at what is the difference between them
How memmove is different from memcpy?
-
Memcpy simply copies data one by one from one location to another while memmove copies data first to an intermediate buffer, then from buffer to destination
-
Memcpy doesn't check for overflow or \0 (null terminator)
-
Memcpy leads to to problems when source and destination addresses overlap
With memcpy, the destination cannot overlap the source at all. With memmove it can. This means that memove might be very slightly slower than memcpy because it has to copy into an intermediate buffer then to the destination, as it cannot make the same assumptions.
Below is an exmaple in comparison with memmove and memcpy
Please note that overlap means within the same string
#include <stdio.h>
#include <string.h>
char message2[60] = "abcdefghijklmnopqrstuvwxyz";
char temp[60];
int main(int argc, char const *argv[])
{
strcpy(temp, message2);
printf("\n\nOriginal message: %s", temp);
memcpy(temp + 4, temp + 16, 10);
printf("\nAfter memcpy() without overlap:\t%s", temp);
strcpy(temp, message2);
memcpy(temp + 6, temp + 4, 10);
printf("\nAfter memcpy() with overlap:\t%s", temp);
strcpy(temp, message2);
printf("\n\nOriginal message: %s", temp);
memmove(temp + 4, temp + 16, 10);
printf("\nAfter memmove() without overlap:\t%s", temp);
strcpy(temp, message2);
memmove(temp + 6, temp + 4, 10);
printf("\nAfter memmove() with overlap:\t%s\n", temp);
return 0;
}
The output:-
Original message: abcdefghijklmnopqrstuvwxyz
After memcpy() without overlap: abcdqrstuvwxyzopqrstuvwxyz
After memcpy() with overlap: abcdefefghijklmnqrstuvwxyz
Original message: abcdefghijklmnopqrstuvwxyz
After memmove() without overlap: abcdqrstuvwxyzopqrstuvwxyz
After memmove() with overlap: abcdefefghijklmnqrstuvwxyz
With this article at OpenGenus, you must have the complete idea of the differences with memcpy and memmove. Enjoy.