C memcpy function
last modified April 8, 2025
Memory operations are fundamental in C programming, and memcpy is a
key function for copying data between memory locations. This tutorial covers
memcpy in depth, including its syntax, usage, and potential
pitfalls. We'll explore practical examples and discuss safer alternatives for
critical applications. Understanding memcpy helps optimize memory
operations while maintaining program safety and reliability.
What Is memcpy?
The memcpy function copies a block of memory from one location to
another. It's declared in string.h and takes three parameters: the
destination pointer, source pointer, and number of bytes to copy.
memcpy performs a binary copy without checking for overlapping
regions or buffer sizes. For safety-critical code, consider
memmove for overlapping regions or memcpy_s for
bounds-checked copying.
Basic memcpy Usage
This example demonstrates copying data between two arrays using
memcpy.
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
// Copy 14 bytes (including null terminator)
memcpy(dest, src, 14);
printf("Source: %s\n", src);
printf("Destination: %s\n", dest);
return 0;
}
Here, memcpy copies 14 bytes from src to
dest, including the null terminator. The destination buffer must be
large enough to hold the copied data. This is a simple, efficient way to copy
data when you know the exact size needed. Always ensure the destination has
enough space to prevent buffer overflows.
Copying Structures with memcpy
memcpy can efficiently copy entire structures, as shown in this
example.
#include <stdio.h>
#include <string.h>
typedef struct {
int id;
char name[20];
float score;
} Student;
int main() {
Student s1 = {101, "Alice", 95.5};
Student s2;
// Copy the entire structure
memcpy(&s2, &s1, sizeof(Student));
printf("Copied Student:\n");
printf("ID: %d\n", s2.id);
printf("Name: %s\n", s2.name);
printf("Score: %.1f\n", s2.score);
return 0;
}
This example copies a Student structure using memcpy.
The sizeof operator ensures we copy the exact number of bytes
needed. This method is faster than field-by-field assignment for large
structures. Note that this works for simple structures without pointers to
dynamically allocated memory.
Handling Overlapping Memory Regions
This example demonstrates the danger of using memcpy with
overlapping regions.
#include <stdio.h>
#include <string.h>
int main() {
char data[] = "ABCDEFGHIJ";
// Attempt to copy with overlapping regions
memcpy(data + 2, data, 5);
printf("Result: %s\n", data);
return 0;
}
This code shows undefined behavior because memcpy doesn't handle
overlapping memory regions. The source and destination overlap by 3 bytes.
For such cases, memmove should be used instead, as it properly
handles overlaps. The output of this program is unpredictable and may vary
across compilers and platforms.
Safe Alternative: memcpy_s
This example demonstrates the safer memcpy_s function available in
C11.
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
int main() {
char src[10] = "Test";
char dest[5];
// Safe copy with bounds checking
errno_t result = memcpy_s(dest, sizeof(dest), src, sizeof(src));
if (result != 0) {
printf("Error: Buffer too small or invalid parameters\n");
return 1;
}
printf("Copied safely: %s\n", dest);
return 0;
}
memcpy_s adds bounds checking and returns an error if the
destination is too small. This helps prevent buffer overflows. The function
returns zero on success and non-zero on failure. While not universally
available, it's recommended for security-critical code when targeting C11 or
later standards with bounds-checking support.
The macro __STDC_WANT_LIB_EXT1__ is defined as 1 to explicitly
indicate that the program wants to use optional extensions from the C11
standard library. Without this macro, certain safer functions, including
memcpy_s, may not be made available by the compiler. This feature
allows developers to selectively enable additional functionality to improve
security and reliability in their programs.
Copying Partial Arrays
This example shows how to copy a portion of an array using memcpy.
#include <stdio.h>
#include <string.h>
int main() {
int src[] = {1, 2, 3, 4, 5, 6, 7, 8};
int dest[4];
// Copy middle 4 elements (3,4,5,6)
memcpy(dest, src + 2, 4 * sizeof(int));
printf("Copied elements: ");
for (int i = 0; i < 4; i++) {
printf("%d ", dest[i]);
}
printf("\n");
return 0;
}
Here, memcpy copies four integers starting from the third element of
the source array. The size is calculated as 4 * sizeof(int) to get
the correct byte count. This technique is useful for extracting portions of
arrays or buffers. Always verify the destination has sufficient space for the
copied data.
Best Practices for Using memcpy
- Check buffer sizes: Ensure destination has enough space for the copied data.
- Avoid overlapping regions: Use
memmoveif source and destination might overlap. - Consider safer alternatives: Use
memcpy_sin security-critical code when available. - Verify pointer validity: Ensure both source and destination pointers are valid.
- Use correct size calculations: Remember that the size parameter is in bytes.
Source
This tutorial has explored the memcpy function, from basic usage to
advanced considerations. While powerful, always use memory operations carefully
to prevent security vulnerabilities and undefined behavior in your programs.
Author
List C Standard Library.