A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
memcpy copies n bytes from a source address to a destination address. It does not care about types. It does not look for null terminators. It copies raw bytes. This makes it the universal copy function for structs, arrays, binary data, and any contiguous memory block. It has one critical restriction: the source and destination must not overlap. If they do, the behavior is undefined. For overlapping regions, use memmove.
#include <stdio.h>#include <string.h>typedef struct {int id;char name[32];double score;} Student;int main(void) {Student original = {42, "Alex", 95.5};Student copy;memcpy(©, &original, sizeof(Student));printf("Copy: id=%d, name=%s, score=%.1f\n",copy.id, copy.name, copy.score);copy.score = 88.0;printf("Original score still: %.1f\n", original.score);return 0;}
memcpy copied the entire struct byte by byte, including the padding bytes between fields. The copy is independent. Modifying the copy does not affect the original. This is a shallow copy: if the struct contained a pointer, both the original and the copy would point to the same heap allocation. We cover deep copying in the structs module.
#include <stdio.h>#include <string.h>int main(void) {const char *source = "Hello, World!";char dest[6];memcpy(dest, source + 7, 5);dest[5] = '\0';printf("Extracted: \"%s\"\n", dest);return 0;}
source + 7 points to the 'W' in "World!". We copy 5 bytes: W, o, r, l, d. Then we manually null-terminate because memcpy does not add a terminator. It copies exactly the number of bytes you specify. Nothing more. Nothing less.
#include <stdio.h>#include <string.h>int main(void) {char buf[] = "ABCDEFGHIJ";printf("Before: %s\n", buf);memcpy(buf + 2, buf, 5);printf("After memcpy overlap: %s\n", buf);return 0;}
ASan detects the overlap and warns. Without ASan, the result is unpredictable. Some bytes might be copied correctly, others might be overwritten before they are read. The standard says undefined behavior. The fix: use memmove, which handles overlap correctly by copying to a temporary buffer or choosing the copy direction carefully. We cover memmove in a later lesson.
memcpy is the fastest way to move bytes in C. Compilers often replace it with optimized SIMD instructions. It is the workhorse of binary I/O, struct serialization, and buffer management. Just remember: no overlap. Next: memset, for filling memory with a byte pattern.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.