C String memcpy() Function

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
<string.h>

What You’ll Learn

The memcpy() function from <string.h> copies exactly n bytes from a source block to a destination block. It is one of the fastest ways to duplicate strings, arrays, and raw binary data—provided the destination is large enough and the regions do not overlap.

01

Copy n Bytes

Raw transfer.

02

Returns dest

Same pointer.

03

Buffer Size

Avoid overflow.

04

No Overlap

Use memmove.

05

+1 for Strings

Include \0.

06

vs strcpy()

Explicit length.

Definition and Usage

In C, memcpy() is declared in <string.h>. It performs a byte-for-byte copy from src to dest for n bytes. It does not interpret the data as text—it simply moves bytes.

When copying C-strings, you must copy the null terminator if you want dest to be a valid string. That means copying strlen(src) + 1 bytes, not just strlen(src). The destination array must have at least that much space reserved.

💡
Beginner Tip

If source and destination memory regions overlap, memcpy() has undefined behavior. Use memmove() instead when copying within the same buffer or when ranges might overlap.

📝 Syntax

The standard library declaration:

C
void *memcpy(void *dest, const void *src, size_t n);

Parameters

  • dest — pointer to the destination buffer (must hold at least n bytes).
  • src — pointer to the source data to copy from.
  • n — number of bytes to copy.

Return Value

Returns dest (the destination pointer you passed in).

Header

#include <string.h>

⚡ Quick Reference

GoalCallNotes
Copy C-stringmemcpy(d, s, strlen(s) + 1)Includes '\0'
Copy n raw bytesmemcpy(d, s, n)Binary / struct data
Copy prefix onlymemcpy(d, s, 5)First 5 bytes
Overlapping regionsmemmove(d, s, n)Not memcpy
Return valuedestSame as first argument
String
memcpy(d, s, strlen(s)+1)

Full C-string copy

Bytes
memcpy(d, s, n)

Fixed-length copy

Safety
sizeof(dest) >= n

Room for n bytes

Alternative
strcpy(d, s)

Null-terminated strings

Examples Gallery

Compile with gcc memcpy.c -std=c11 -o memcpy. Each example shows safe buffer sizing, null termination, and when to prefer memmove().

📚 Getting Started

Duplicate a C-string into a properly sized destination buffer.

Example 1 — Copy a C-String (with Null Terminator)

Copy "Hello, C!" including the terminating '\0'.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char source[] = "Hello, C!";
    char destination[16];

    size_t bytes = strlen(source) + 1;
    memcpy(destination, source, bytes);

    printf("Source:      %s\n", source);
    printf("Destination: %s\n", destination);
    printf("Bytes copied: %zu\n", bytes);

    return 0;
}

How It Works

Nine visible characters plus one null byte equals 10 bytes total. destination[16] has enough room. Without the + 1, the copy would omit '\0' and printing destination would be unsafe.

Example 2 — Copy Only the First n Bytes

Copy a prefix without making a full string—useful for fixed-width fields.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    const char *source = "Hello, C Programming!";
    char destination[8];

    memcpy(destination, source, 7);
    destination[7] = '\0';

    printf("Prefix copy: %s\n", destination);

    return 0;
}

How It Works

Seven bytes copy "Hello, ". Because memcpy does not add a terminator, we manually set destination[7] = '\0' before treating the result as a C-string.

📈 Practical Patterns

Binary data, return value, and overlap safety.

Example 3 — Copy a Binary Buffer

memcpy() copies any bytes—not only printable characters.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    unsigned char src[] = { 0xDE, 0xAD, 0xBE, 0xEF };
    unsigned char dst[4];

    memcpy(dst, src, sizeof src);

    printf("Copied bytes: %02X %02X %02X %02X\n",
           dst[0], dst[1], dst[2], dst[3]);

    return 0;
}

How It Works

Each byte is copied verbatim. This pattern appears in network code, file I/O, and embedded systems where data is not null-terminated text.

Example 4 — Using the Return Value

memcpy returns dest, which can simplify chained operations.

C
#include <stdio.h>
#include <string.h>

int main(void) {
    char buffer[32];
    const char *tag = "C";

    char *end = memcpy(buffer, "Hello, ", 7);
    end = memcpy(end, tag, strlen(tag) + 1);

    printf("%s\n", buffer);

    return 0;
}

How It Works

The first copy writes "Hello, " at the start of buffer. The returned pointer (buffer) is advanced implicitly by copying the next piece at offset 7. Ensure the total size still fits in buffer.

Example 5 — Overlap: memcpy() vs memmove()

When regions overlap, use memmove()—not memcpy().

C
#include <stdio.h>
#include <string.h>

int main(void) {
    char text[] = "abcdef";

    /* Safe: shift "bcdef" left by one position */
    memmove(text, text + 1, 5);
    text[5] = '\0';

    printf("After memmove: %s\n", text);

    /* memcpy(text, text + 1, 5);  // UNDEFINED if overlapping */

    return 0;
}

How It Works

Source and destination both lie inside text, so they overlap. memmove copies in the correct direction to avoid clobbering unread data. Using memcpy here would be undefined behavior even if it sometimes appears to work.

🚀 Common Use Cases

  • String duplication — copy text into a new buffer when you control the destination size.
  • Array copying — duplicate struct arrays or byte buffers in one call.
  • Protocol packets — assemble fixed-layout messages from template bytes.
  • Graphics / audio — copy pixel or sample blocks between buffers.
  • Serialization — move raw memory into an output buffer before writing to disk or network.

🧠 How memcpy() Works

1

You pass dest, src, and n

The function receives destination and source addresses plus the byte count to transfer.

Input
2

Copy n bytes

Each byte from src is written to the corresponding offset in dest.

Transfer
3

Return dest

The original destination pointer is returned for convenience.

Result
=

Destination updated

The first n bytes of dest now match src. Verify size and overlap rules were respected.

📝 Notes

  • Buffer sizedest must have room for at least n bytes. Writing beyond the buffer is undefined behavior.
  • No overlap — if src and dest overlap, use memmove() instead.
  • Null terminator — copying strlen(s) bytes alone does not make a C-string; include + 1 or append '\0' manually.
  • Not for allocationmemcpy does not allocate memory; you must provide both buffers.
  • Order of evaluation — do not rely on overlapping read/write side effects with memcpy.

⚡ Optimization

Standard library memcpy() implementations are heavily optimized—often using word-aligned bulk copies. For large transfers, calling memcpy directly beats a naive byte loop. Copy only the bytes you need; avoid redundant copies in hot paths.

Conclusion

memcpy() is the standard way to copy raw memory in C. Size your destination correctly, include the null byte when duplicating strings, and switch to memmove() when regions might overlap.

Practice the examples, then continue to memmove() for safe copying when source and destination share the same buffer.

💡 Best Practices

✅ Do

  • Ensure dest has at least n bytes of space
  • Copy strlen(src) + 1 for full C-strings
  • Use memmove when buffers might overlap
  • Prefer sizeof(array) for fixed-size copies
  • Zero-terminate manually after partial string copies

❌ Don’t

  • Copy into a buffer smaller than n
  • Use memcpy on overlapping regions
  • Forget the null terminator when you need a C-string
  • Assume memcpy allocates memory
  • Use memcpy where strcpy is clearer and safe

Key Takeaways

Knowledge Unlocked

Five things to remember about memcpy()

Use these points whenever you copy memory in C.

5
Core concepts
📝 02

Returns dest

Same pointer.

Return
🔒 03

Size dest

Prevent overflow.

Safety
📈 04

+1 for \0

String copies.

Strings
💬 05

Use memmove

If overlap.

Rule

❓ Frequently Asked Questions

memcpy() copies n bytes from a source memory block to a destination block. It returns the dest pointer. The copy is a raw byte transfer—it does not add a null terminator unless you include that byte in n.
void* memcpy(void* dest, const void* src, size_t n); Include <string.h>. dest is where bytes are written, src is the source, and n is how many bytes to copy.
It returns dest—the same pointer you passed as the destination. This allows chaining such as memcpy(a, b, n) in expressions, though assigning the result is optional.
memcpy() requires that src and dest do not overlap; overlapping copies have undefined behavior. memmove() handles overlapping regions safely by copying in the correct direction. Use memmove when buffers might overlap.
Copy strlen(src) + 1 bytes to include the terminating '\0': memcpy(dest, src, strlen(src) + 1). Ensure dest has at least that many bytes allocated. For plain string duplication, strcpy() or strncpy() may be clearer.
Yes. If n is larger than the destination buffer, memcpy writes past the end—undefined behavior and a common security bug. Always ensure dest has room for at least n bytes before calling memcpy.
Did you know?

Many compilers treat memcpy of small, constant sizes as inline instructions. Even so, the C standard still requires you to respect buffer bounds and the no-overlap rule—optimizations do not make invalid calls safe.

Continue the String Functions Series

Master memory copying with memcpy(), then learn overlap-safe copies with memmove().

Next: memmove() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful