C Library Function - memmove()
memmove()is the C standard library<string.h>memory operation function in it, used to copy a specified number of bytes from the source address to the destination address, and can safely handle overlapping memory cases.
Word Definitions:memmoveYesmemory moveAbbreviation of (memory move), meaning moving data in memory.
C Library Functionsvoid *memmove(void *str1, const void *str2, size_t n)fromstr2Copynbytes tostr1。
Difference from memcpy():
- When the destination region and the source region have memory overlap,
memmove()it can guarantee that before the source data is overwritten, the overlapping bytes are safely transferred to the destination region first, therefore compared tomemcpy()more reliable. - when the destination region and the source region do not overlap at all,
memmove()the behavior andmemcpy()Same. - when it is uncertain whether the two memory regions overlap, priority should be given to using
memmove()。
Function Declaration
void *memmove(void *str1, const void *str2, size_t n)
Parameter description
- str1: destination address, pointing to the memory area used to store the copied content (type cast to
void*)。 - str2: source address, pointing to the starting position of the data to be copied (type cast to
const void*)。 - n: the number of bytes to copy (
size_ttype).
Return Value
returns a pointer to the destination storage areastr1pointer (same as the passed-instr1same).
Header file
#include <string.h>
Example
Example 1: Basic usage
The following example demonstratesmemmove()Usage in both non-overlapping and overlapping scenarios:
Example
#include <string.h>
int main()
{
/* Scenario 1: non-overlapping memory copy */
char dest[] = "oldstring";
char src[] = "newstring";
printf("Before non-overlapping copy:dest = %s, src = %s\n", dest, src);
memmove(dest, src, 9);
printf("After non-overlapping copy:dest = %s, src = %s\n", dest, src);
/* Scenario 2: overlapping memory copy (where memmove has the advantage) */
char str[] = "123456789";
printf("\nBefore overlapping copy:%s\n", str);
memmove(str + 2, str, 6);
printf(After overlapping copy: %s\n", str);
return 0;
}
Run result:
非重叠拷贝前:dest = oldstring, src = newstring 非重叠拷贝后:dest = newstring, src = newstring 重叠拷贝前:123456789 重叠拷贝后:121234569
Code Analysis:
- In scenario 1,
destandsrcare two independent arrays, no overlap,memmove(dest, src, 9)willsrcthe first 9 bytes are copied unchanged todest。 - In scenario 2,
str + 2(destination) andstr(source) points to an overlapping region within the same array,memmovewill first save the overwritten data, then complete the copy, so the result is correct. - If scenario 2 is replaced with
memcpy, may produce incorrect results on some compilers or platforms, becausememcpydoes not guarantee handling of overlapping cases.
Example 2: Handling overlapping memory
When two memory areas overlap,memmove()can still give the correct result:
Example
#include <string.h>
int main()
{
char str[] = "memmove can be very useful";
printf("Before: %s\n", str);
/* Copy 7 bytes starting at position 11 to position 5; the two regions overlap */
memmove(str + 5, str + 11, 7);
printf("After: %s\n", str);
return 0;
}
Run result:
Before: memmove can be very useful After: memmove can be very useful
Code Analysis:
- In the original string, starting from position 5 is
"ve can be very useful", the 7 bytes starting from position 11 are"can be"(including the trailing space). memmove(str + 5, str + 11, 7)will"can be"moved to position 5, the two regions overlap, butmemmoveIt will select a forward or reverse copy strategy based on address size to ensure data integrity.- After copying, the content starting from position 5 becomes
"can be", while the remaining characters remain unchanged.
Example 3: Compare memcpy() and memmove()
The following example shows that under the same overlapping scenario, the two functions may produce different results:
Example
#include <string.h>
int main()
{
char str1[] = "abcdefghij";
char str2[] = "abcdefghij";
printf("Original: %s\n", str1);
/* Using memcpy: behavior is undefined when overlapping */
memcpy(str1 + 2, str1, 5);
printf("memcpy: %s\n", str1);
/* Using memmove: behavior is guaranteed when overlapping */
memmove(str2 + 2, str2, 5);
printf("memmove: %s\n", str2);
return 0;
}
Run result:
Original: abcdefghij memcpy: ababababij memmove: ababcdfghij
Description: in this example,memcpyBecause byte-by-byte forward copy causes the source data to be overwritten early, the output does not match expectations; whilememmoveit detects overlap and uses reverse copy, so the result is correct. Different platforms or compilers'memcpyimplementation behavior may be inconsistent, so it should always be used when encountering overlapping scenarios.memmove。
Example 4: Copy the specified number of bytes
memmove()is a byte-level operation and does not automatically write the string terminator; when using it, you need to manually add it.'\0':
Example
#include <string.h>
int main()
{
char src[] = "Hello, World!";
char dest[20];
/* Copy only the first 5 bytes */
memmove(dest, src, 5);
dest[5] = '\0'; /* Manually add the string terminator */
printf("Source: %s\n", src);
printf("Dest: %s\n", dest);
printf("Length: %zu\n", strlen(dest));
return 0;
}
Run result:
Source: Hello, World! Dest: Hello Length: 5
Code Analysis:
memmove(dest, src, 5)only copy the first 5 bytes ('H' 'e' 'l' 'l' 'o')。memmove()will not automatically write at the end of the destination'\0', if omitteddest[5] = '\0', subsequent string operations (such asprintf、strlen) will read indeterminate memory, resulting in undefined behavior.
Difference from memcpy()
| Features | memcpy() | memmove() |
|---|---|---|
| Overlapping memory handling | The behavior is undefined, which may produce wrong results | Safe handling, ensuring correct copying |
| Implementation Approach | Directly copy byte-by-byte in order | Detects overlap direction, chooses forward or reverse copy |
| Performance | Usually slightly faster (no overlap detection overhead) | Slightly slower (includes overlap detection logic) |
| Usage suggestions | Use when confirming that the source and destination do not overlap at all | Use when there is overlap or when it is uncertain whether there is overlap. |
other extensions