C String memchr() Function

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

What You’ll Learn

The memchr() function from <string.h> locates the first occurrence of a byte value within a memory region of length n. Unlike strchr(), it does not require a null terminator—making it ideal for strings, fixed buffers, and binary data alike.

01

Search n Bytes

Bounded scan.

02

Returns void*

Or NULL.

03

Get Index

result - base

04

Any Memory

Not just strings.

05

unsigned char

Byte comparison.

06

vs strchr()

Null-terminated.

Definition and Usage

In C, memchr() is declared in <string.h>. It examines exactly n bytes starting at pointer s, comparing each byte to c after converting c to unsigned char. The scan stops at the first match or after n bytes—whichever comes first.

When a match is found, the return value points into the original memory block. Subtract the base pointer ((char*)result - (char*)s) to get a zero-based index. Always check for NULL before using the result.

💡
Beginner Tip

For C-strings you often pass strlen(str) as n so the search covers the visible characters but not the terminating '\0'. To include the null byte in the search range, use strlen(str) + 1.

📝 Syntax

The standard library declaration:

C
void *memchr(const void *s, int c, size_t n);

Parameters

  • s — pointer to the memory block to search.
  • c — byte value to find, passed as int and converted to unsigned char (e.g. 'C' or 67).
  • n — maximum number of bytes to examine.

Return Value

Pointer to the first matching byte in the searched region, or NULL if not found within n bytes.

Header

#include <string.h>

⚡ Quick Reference

DataCallResult
"Hello, C!"memchr(s, 'C', strlen(s))pointer at index 7
"Hello, C!"memchr(s, 'z', strlen(s))NULL
"user@mail.com"memchr(s, '@', strlen(s))pointer at index 4
first 5 bytes onlymemchr(buf, 'X', 5)search stops at byte 5
index from pointer(char*)result - (char*)szero-based position
Basic
memchr(s, 'C', n)

Find byte in n bytes

C-string
memchr(str, ch, strlen(str))

Common text pattern

Check found
if (p != NULL)

Before using p

Alternative
strchr(str, ch)

Null-terminated strings

Examples Gallery

Compile with gcc memchr.c -std=c11 -o memchr. Each example shows bounded search, null checks, and practical patterns for text and binary buffers.

📚 Getting Started

Locate a character in a C-string and report its index.

Example 1 — Basic memchr() on a String

Search for 'C' in "Hello, C Programming!". The match is at zero-based index 7.

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

int main(void) {
    const char *str = "Hello, C Programming!";
    char searchChar = 'C';
    size_t len = strlen(str);

    void *result = memchr(str, searchChar, len);

    if (result != NULL) {
        size_t index = (const char *)result - str;
        printf("'%c' found at index %zu (1-based position %zu).\n",
               searchChar, index, index + 1);
    } else {
        printf("'%c' not found.\n", searchChar);
    }

    return 0;
}

How It Works

strlen(str) supplies the byte count so memchr scans only the visible characters. Pointer subtraction converts the result address into a zero-based index; add 1 for human-friendly “position” numbering.

Example 2 — Byte Not Found

When the byte is absent within the n-byte range, memchr returns NULL.

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

int main(void) {
    const char *word = "Hello";
    void *found = memchr(word, 'z', strlen(word));

    if (found == NULL) {
        printf("'z' is not in the first %zu bytes.\n", strlen(word));
    } else {
        printf("Found at %td\n", (char *)found - word);
    }

    return 0;
}

How It Works

All five bytes are compared; none equals 'z', so the function returns NULL. Never dereference or subtract pointers when the result is null.

📈 Practical Patterns

Bounded search, binary data, and comparison with strchr().

Example 3 — Search Only the First n Bytes

Limiting n lets you search a prefix of a buffer—useful when data continues beyond a logical boundary.

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

int main(void) {
    const char *text = "ABC-DEF-GHI";
    void *dash = memchr(text, '-', 4);   /* only "ABC-" */

    if (dash != NULL) {
        printf("Dash in first 4 bytes at index %td\n",
               (const char *)dash - text);
    } else {
        printf("No dash in first 4 bytes.\n");
    }

    dash = memchr(text, '-', strlen(text));
    if (dash != NULL) {
        printf("Dash in full string at index %td\n",
               (const char *)dash - text);
    }

    return 0;
}

How It Works

The first call examines only indices 0–3 ("ABC-"), finding '-' at index 3. The second call scans the entire string and finds the same first dash. A smaller n could miss bytes that appear later.

Example 4 — Search a Binary Buffer

memchr() shines when data is not a C-string—no '\0' is required.

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

int main(void) {
    unsigned char packet[] = { 0x01, 0x02, 0xFF, 0x04, 0x05 };
    size_t packetLen = sizeof packet;

    void *marker = memchr(packet, 0xFF, packetLen);

    if (marker != NULL) {
        size_t offset = (unsigned char *)marker - packet;
        printf("0xFF found at offset %zu\n", offset);
    } else {
        printf("Marker byte not found.\n");
    }

    return 0;
}

How It Works

The buffer contains raw bytes including 0xFF, which is not a printable character. strchr() would not be appropriate here because there is no null terminator defining the end.

Example 5 — memchr() vs strchr()

For null-terminated strings, both functions can locate a character—but they differ in how the search bound is defined.

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

int main(void) {
    const char *email = "user@example.com";

    char *at1 = strchr(email, '@');
    void *at2 = memchr(email, '@', strlen(email));

    if (at1 != NULL && at2 != NULL) {
        printf("strchr index:  %td\n", at1 - email);
        printf("memchr index:  %td\n", (char *)at2 - email);
        printf("Same match:    %s\n",
               (at1 == at2) ? "yes" : "no");
    }

    return 0;
}

How It Works

On a normal C-string, memchr(str, ch, strlen(str)) usually matches strchr(str, ch) for the first occurrence. Choose memchr when you need an explicit byte limit or work with non-string memory.

🚀 Common Use Cases

  • Delimiter search — locate '@', ':', '/', or '=' within a known-length buffer.
  • Binary protocols — find marker bytes in packets or firmware images.
  • Partial buffer scan — search only the first n bytes of a larger allocation.
  • Safe string search — avoid reading past a buffer when length is known but the data may lack '\0'.
  • Validation — verify a required character exists before parsing further.

🧠 How memchr() Works

1

You pass s, c, and n

The function receives a memory address, the byte to find, and the maximum bytes to read.

Input
2

Scan up to n bytes

Each byte is compared to (unsigned char)c. The scan stops at a match or after n bytes.

Search
3

Match or exhausted range

On success, return the address of the matching byte. Otherwise return NULL.

Result
=

Pointer or NULL

Use the pointer for suffix access, or subtract the base address to compute an offset.

📝 Notes

  • Comparison uses unsigned char semantics—negative int values for c still map to 0–255.
  • Always test for NULL before dereferencing or subtracting pointers.
  • The return pointer points into the original block—not a new allocation.
  • If n is 0, no bytes are examined and the function returns NULL.
  • For null-terminated strings only, strchr() is simpler; pass strlen(str) to memchr when mimicking strchr.

⚡ Optimization

memchr() is highly optimized in standard C libraries and is the right tool for bounded byte search. Pass the smallest accurate n you can to avoid unnecessary work. For repeated searches, advance the start pointer and reduce n rather than rescanning from the beginning each time.

Conclusion

memchr() is the standard way to find a byte within a fixed-size memory region. Remember the three parameters—pointer, byte value, and count—check for NULL before use, and prefer strchr() when you already have a null-terminated C-string and no length limit is needed.

Practice the examples, then continue to memcmp() for comparing two memory blocks byte by byte.

💡 Best Practices

✅ Do

  • Check result != NULL before use
  • Pass correct n—never read past the buffer
  • Use strlen(str) for visible C-string characters
  • Cast to char* or unsigned char* for pointer math
  • Prefer memchr for binary buffers without '\0'

❌ Don’t

  • Dereference a NULL return pointer
  • Subtract pointers when result is NULL
  • Pass n larger than the actual buffer size
  • Assume memchr stops at '\0'—only n limits the scan
  • Confuse byte search (memchr) with block compare (memcmp)

Key Takeaways

Knowledge Unlocked

Five things to remember about memchr()

Use these points whenever you search memory for a byte value.

5
Core concepts
📝 02

void* Result

Or NULL.

Return
🔢 03

Get Offset

result - base

Pattern
📈 04

Binary Safe

No null needed.

Behavior
💬 05

vs strchr()

String alternative.

Compare

❓ Frequently Asked Questions

memchr() scans the first n bytes of a memory block for the first occurrence of a character (byte value). It returns a pointer to that byte, or NULL if the value is not found within the n-byte range.
void* memchr(const void* s, int c, size_t n); Include <string.h>. Parameter s points to the memory to search, c is the byte to find (converted to unsigned char), and n is how many bytes to examine.
A pointer to the first matching byte inside the searched region, or NULL if no match exists within n bytes. Cast to char* when working with text.
memchr() scans exactly n bytes and works on any memory block—including binary data without a null terminator. strchr() scans a null-terminated C-string until '\0'. For plain text strings, strchr() is often simpler; memchr() gives you explicit length control.
Yes. Because you pass a byte count n, memchr() does not require a null terminator. It is commonly used on buffers, structs, and network packets—not only on strings.
Yes. The byte value must match exactly after conversion to unsigned char. 'A' (65) and 'a' (97) are different bytes.
Did you know?

The mem* family (memchr, memcmp, memcpy, memmove, memset) operates on raw memory bytes. The str* family operates on null-terminated strings. Pick memchr when the valid length is known but the data may contain embedded null bytes.

Continue the String Functions Series

Master byte search with memchr(), then learn memory comparison with memcmp().

Next: memcmp() →

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