pointers-memory · beginner · ~15 min

Const-Correct Pointer Audit

Maintain strict const correctness between immutable read-only buffers and writable output buffers.

Challenge

In C, const int *p denotes a pointer to constant data (the pointee cannot be modified), whereas int * const p denotes a constant pointer (the pointer address cannot be changed). Enforcing const correctness guarantees that read-only inspect operations never accidentally mutate input buffers.

Your Task

Implement:

int count_matching_bytes(const uint8_t *src, size_t len, uint8_t target);
int copy_filtered_bytes(uint8_t *dest, size_t dest_cap, const uint8_t *src, size_t src_len, uint8_t exclude_byte, size_t *out_written);

Rules

  1. In count_matching_bytes:
    • If src == NULL or len == 0, return 0.
    • Count and return the number of occurrences of target in src[0..len-1].
  2. In copy_filtered_bytes:
    • If dest == NULL, src == NULL, out_written == NULL, or dest_cap == 0, return -1.
    • Copy each byte from src to dest except bytes equal to exclude_byte.
    • If the number of matching bytes exceeds dest_cap, return -1 and set *out_written = 0 (leaving dest uncommitted).
    • On success: write bytes to dest, set *out_written to the count of written bytes, and return 0.

Example

uint8_t data[] = {1, 2, 3, 2, 4};
count_matching_bytes(data, 5, 2); // returns 2
uint8_t out[5]; size_t w = 0;
copy_filtered_bytes(out, 5, data, 5, 2, &w); // returns 0, w == 3, out = {1, 3, 4}

Input format

Pointers to source (const) and destination buffers.

Output format

Returns match counts or status code 0/-1.

Constraints

Zero dynamic allocations. Respect const qualifier.

Starter code

#include <stddef.h>
#include <stdint.h>

int count_matching_bytes(const uint8_t *src, size_t len, uint8_t target) {
    (void)src; (void)len; (void)target;
    return 0;
}

int copy_filtered_bytes(uint8_t *dest, size_t dest_cap, const uint8_t *src, size_t src_len, uint8_t exclude_byte, size_t *out_written) {
    (void)dest; (void)dest_cap; (void)src; (void)src_len; (void)exclude_byte; (void)out_written;
    return -1;
}

Common mistakes

Casting away const; writing to dest before verifying total capacity.

Edge cases to handle

Excluding byte not present copies full source; dest_cap too small returns -1 atomically.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.