The format for the memmove function is outlined below:
void *memmove(void *strng1, const void *strng2, size_t n);
Parameters Passed inside the Function
- strng1: It is the pointer to the memory block where you wish to copy the contents of the source memory block. The datatype for the pointer is *void.
- strng2: It is the pointer to the memory block from where you want to copy the contents to the destination memory block. The datatype for the pointer is *void.
- n: It is the number of bytes of data to be moved from one location to another.
Return
It yields a pointer that references the location of the memory block, identified in the syntax as strng1.
Implementation of memmove function in C Programming
Let's proceed with the implementation of the memmove function. Within this function, we aim to transfer the data from the original array to the destination array.
#include <stdio.h>
#include <string.h>
int main ()
{
//The first step is to initialize the source and destination array.
char new[] = "The content will be loaded soon.\n";
char orgnl[] = "The content is to be transferred to a new location.\n";
//Print the contents before performing memmove function.
printf("Before implementing memmove destination and source memory block respt is\n >> new = %s\n orgnl = %s\n", new, orgnl);
memmove(new, orgnl, sizeof(orgnl));
//Display the content in both new and orgnl array after implementing memmove.
printf("After memmove >> new = %s\n orgnl = %s\n", new, orgnl);
return 0;
}
Output:
[Program Output]
Some Facts related to the memmove function in C programming:
When examining the memmove function, it is crucial to note its capabilities and considerations. Unlike memcpy, which is recommended when the source and destination buffers do not overlap, memmove can handle overlapping buffers. In scenarios where buffer overlap occurs, opting for memmove prevents undefined behavior. For instance, suppose you have two arrays, arr1 and arr2, with some overlapping elements. In this case, employing memmove ensures the correct transfer of data between the arrays, addressing potential issues that may arise from the overlap.
Let us discuss the example:
#include <string.h>
#include <stdio.h>
int main()
{
char strng1[1000] = "This string will be used to implement the memmove() function.";
char strng2[1000] = "This string will be used to implement the memcpy() function.";
//Use of memmove
printf( "Function:\tUsing the memmove() function while the src and dest overlap\n\n" );
printf( "Orignal content of the first string:\t%s\n",strng1);
//the source content will replace
printf( "Source for copying the content:\t%s\n",strng1 + 5 );
//the destination content will be repl
printf( "Destination to copy the content:\t%s\n\n",strng1 + 11 );
memmove( strng1 + 11, strng1 + 5, 29 );
printf( "Result after implementing the memmove()function:\t%s\n",strng1 );
printf( "Length of the strng1:\t%d characters\n\n", strlen( strng1 ) );
//Use of memcpy
printf( "Function:\tUsing the memcpy() function while the src and dest overlap\n\n" );
printf( "Orignal content of the second string::\t%s\n",strng2);
//the source content will replace
printf( "Source for copying the content:\t%s\n",strng2 + 5 );
//the destination content will be replaced
printf( "Destination to copy the content:\t%s\n\n",strng2 + 11 );
memcpy( strng2 + 11, strng2 + 5, 29 );
printf( "Result after implementing the memcpy()function:\t%s\n",strng2 );
printf( "Length of the strng2:\t%d characters\n\n", strlen( strng2 ) );
return 0;
}
Output:
The runtime duration of both functions, namely memcpy and memmove, is nearly identical, albeit subject to potential variations based on the platform or compiler being used. While there may be slight fluctuations, the speed of memcpy compared to memmove can vary marginally, with one occasionally outperforming the other.
//include all the necessary header files
#include <string.h>
#include <stdio.h>
//clock() function is defined in time.h header file.
#include <time.h>
//define the size of the buffer
#define BUFFERSIZE (100 * 1024) //It is equal to 100kb
#define LOOP 10000
int main()
{
char destn[BUFFERSIZE] = {0};
char source[BUFFERSIZE] = {0};
int i = 0;
double t_spent;
clock_t start, end;
//Execute the memmove() function
//Start the clock as the execution begins
start = clock();
for ( i = 0; i < LOOP; i++)
{
memmove(destn,source,BUFFERSIZE);
}
// Store the last time recorded by the clock on completion of the execution of the function
end = clock();
// Determine the total time taken from the beginning to the end of execution of the program.
t_spent = (double)(end - start) / CLOCKS_PER_SEC;
printf("memmove() took %f seconds to complete\n", t_spent);
//Execute the memcpy() function
//Start the clock as the execution begins
start = clock();
for ( i = 0; i < LOOP; i++)
{
memcpy(destn,source,BUFFERSIZE);
}
// Store the last time recorded by the clock on completion of the execution of the function
end = clock();
// Determine the total time taken from the beginning to the end of execution of the program.
t_spent = (double)(end - start) / CLOCKS_PER_SEC;
printf("memcpy() took %f seconds to complete\n", t_spent);
return 0;
}
Output:
The primary contrast in functionality between the memmove and memcpy functions lies in their directional capabilities. Unlike memcpy, which operates unidirectionally, memmove is capable of bidirectional movement. This means that memmove can relocate bytes both forwards and backwards, whereas memcpy is limited to only forward movement.
Implementing your memmove function in C Programming
The built-in function specified in the string.h header file is highly effective and covers all potential scenarios that a programmer might encounter when transferring data from one place to another. Therefore, unless there is a specific need to create a custom memmove function, it is advisable for the user to avoid doing so.
Implementing the memmove operation closely resembles the memcpy function, with the added consideration for overlapping memory regions. This additional factor increases the complexity of the program compared to the memcpy function.
This also raises the space complexity of the program because it necessitates the initialization of a temporary array. This array will be employed to handle situations where there is overlap.
All the characters designated for relocation will initially be stored in a temporary array before being transferred to the intended destination location.
void * my_memmove(void* destn, const void* src, unsigned int n)
{
char *pDest = (char *)destn;
const char *pSrc =( const char*)src;
//allocation of the memory block for the temp array
char *temp = (char *)malloc(sizeof(char ) * n);
if(NULL == temp)
{
return NULL;
}
else
{
unsigned int i = 0;
//Copy the content from the src array to temp array first
for(i =0; i < n ; ++i)
{
*(temp + i) = *(pSrc + i);
}
//copy the content from the temp array to the destination array
for(i =0 ; i < n ; ++i)
{
*(pDest + i) = *(temp + i);
}
free(temp); //free allocated memory
}
return destn;
}
Let's create a driver program to verify the functionality of the custom function we have developed.
#include <iostream>
//to use the malloc function in your code ensure to
//include cstdlib
#include <cstdlib>
void * my_memove(void* destn, const void* source, unsigned int n)
{
char *pDest = (char *)destn;
const char *pSrc =( const char*)source;
//allocate memory for tmp array
char *temp = (char *)malloc(sizeof(char ) * n);
if(NULL == temp)
{
return NULL;
}
else
{
unsigned int i = 0;
// Begin with copying the contents
//from source to the temp
for(i =0; i < n ; ++i)
{
*(temp + i) = *(pSrc + i);
}
//Use the copied content in temp to move the contents in the destn
for(i =0 ; i < n ; ++i)
{
*(pDest + i) = *(temp + i);
}
free(temp); //free the resources allocated to the temp
}
return destn;
}
int main()
{
char Src[] = "This is the content to be copied.";
// The destination string size is 14.
char Dest[16] = {0};
// Lets begin with copying the content that is stored in Src into the Dest
//Use your own my_memove function
my_memove(Dest, Src, 12);
printf("String after copying the n bytes: %s\n", Dest);
int dSrc[] = {20, 100, 30, 50, 70};
int n = sizeof(dSrc)/sizeof(dSrc[0]);
int dDestn[n], index = 0;
// Lets begin with copying the content that is stored in dSrc into the dDest
//Use your own my_memove function
my_memove(dDestn, dSrc, sizeof(dSrc));
printf("\nNow after copying the array it is: ");
for (index=0; index<n; index++)
{
printf("%d ", dDestn[index]);
}
return 0;
}
Output:
[Program Output]
In the preceding code snippet, the driver code has been employed. The string and array have been duplicated by invoking the my_memove function as outlined earlier. A temporary array was utilized to handle any overlapping scenarios effectively. Consequently, both the string and array were successfully duplicated, demonstrating the flawless execution of our function.