The memcpy function in C copies n characters from the object pointed to by src into the object pointed to by dst.
In this blog post I will not explain about the memcpy but I will explain the common issues which occurs if not use the memcpy function properly in C programming.
So, let’s see the scenarios where memcpy function does not behave properly.
Few Common Issues in Using memcpy function in C:
1. Memory or Region Overlap:
If copying takes place between objects that overlap, the behavior is undefined. That means memcpy function might does not give the expected result when the memory regions of source and destination memory overlap.
Let’s consider the following code:
#include <string.h> #include <stdio.h> int main() { char str[50] = "I am going from Delhi to Gorakhpur"; printf( "Function:\tmemcpy with overlap\n" ); /* Copying takes place between objects that overlap, so the behavior is undefined. */ memcpy(str + 5, str, 8); printf("%s\n", str); return 0; }
In the above example code, you can see memcpy function is copying 8 bytes from the beginning of source to its own position starting at index 5. Here source and destination memory are overlapping. See the below image for better understanding,
In memory overlapping case C standard state that memcpy function behavior is undefined. So, the output of the above code is non-predictable. This is the most common issues in using memcpy that done by the newbie.
Now I believe you are thinking about the solution. Don’t worry you don’t think too much about this issue. The C standard already provided memmove function to handle such type of cases where memory is overlapping.
2. Invalid Objects:
The memcpy() does not check the validity of the passed arguments that means source and destination objects.
Let’s consider the few examples,
Example-1:
#include<stdio.h> #include<string.h> int main() { //Uninitialized Pointers: char *src; char dst[12] = {0}; memcpy(dst,src,12); return 0; }
Example-2:
#include<stdio.h> #include<string.h> int main() { char src[20] ="amlendra"; //Uninitialized Pointers: char* dst; memcpy(dst,src,sizeof(src)); return 0; }
In both example codes behavior of memcpy() would be undefined because you are passing uninitialized pointers as the arguments.
3. Accessed beyond the end of an object:
If you will try to access the memory of the source or destination object beyond their allocated space using the memcpy() then, the behavior is undefined.
Consider the below examples,
#include<stdio.h> #include<string.h> int main() { char src[12] ="amlendra"; char dst[5]; /*Copy the data of source to destination using memcpy*/ memcpy(dst, src, 10); /* memcpy() try to copy 10 bytes to a destination array of size 5*/ return 0; }
In the above code, the source array src contains a string of length 9 characters including the terminating null-character (\0). The destination array dst size is 5 that means it can store maximum 5 characters including the terminating null-character.
In the code, the memcpy() tries to copy 10 bytes from src to dst, that accessed the dst beyond the allocated space. It causes the undefined behavior because as per the C standard if an array is accessed beyond the end of an object, the behavior is undefined.
4. null-terminator in strings:
If you are using memcpy with null terminator strings, be careful because memcpy() does not automatically add the null-terminator in destination object.
Let’s take an example,
#include<stdio.h> #include<string.h> int main() { char src[12] ="amlendra"; char dst[12]; /*Copy the 5 character of source to destination using memcpy*/ memcpy(dst, src, 5); return 0; }
In the above example code, memcpy function is used to copy 5 characters from the source array to the destination array. Here memcpy() does not automatically add the null terminators to the destination array. It leads to unexpected behavior when the destination array is treated as a C-style string.
You can solve this issue by explicitly adding the null character to the destination array but make sure that space must be available. See the below code,
#include<stdio.h> #include<string.h> int main() { char src[12] ="amlendra"; char dst[12]; /*Copy the 5 character of source to destination using memcpy*/ memcpy(dst, src, 5); // Adding null-terminator manually in dst dst[5] = '\0'; return 0; }