pointers-memory · intermediate · ~15 min
Allocate, manage, and free contiguous C99 flexible array members safely.
C99 flexible array members (type member[]) placed as the last element of a struct allow allocating a struct and its variable-length payload in a single contiguous dynamic memory block.
Given the dynamic buffer struct:
typedef struct {
uint32_t capacity;
uint32_t length;
uint8_t data[]; // flexible array member
} DynBuffer;
Implement:
DynBuffer *dyn_buffer_create(size_t capacity);
int dyn_buffer_append(DynBuffer *buf, const uint8_t *bytes, size_t len);
void dyn_buffer_free(DynBuffer *buf);
dyn_buffer_create:capacity > 1024 * 1024 (1MB) or capacity check overflows sizeof(DynBuffer) + capacity, return NULL.sizeof(DynBuffer) + capacity bytes.capacity = (uint32_t)capacity, length = 0.DynBuffer.dyn_buffer_append:buf == NULL, bytes == NULL, or len == 0, return -1.buf->length + len > buf->capacity, return -1 (buffer capacity exceeded).bytes into buf->data + buf->length.buf->length += len and return 0.dyn_buffer_free:buf != NULL, free buf.DynBuffer *b = dyn_buffer_create(10);
uint8_t msg[] = "ABC";
dyn_buffer_append(b, msg, 3); // returns 0, length == 3
dyn_buffer_free(b);
capacity: initial byte capacity; buf: DynBuffer pointer; bytes: byte array to append.
Returns pointer to DynBuffer or integer status 0/-1.
Single allocation for header + flexible array member. Zero memory leaks.
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct {
uint32_t capacity;
uint32_t length;
uint8_t data[];
} DynBuffer;
DynBuffer *dyn_buffer_create(size_t capacity) {
(void)capacity;
return NULL;
}
int dyn_buffer_append(DynBuffer *buf, const uint8_t *bytes, size_t len) {
(void)buf; (void)bytes; (void)len;
return -1;
}
void dyn_buffer_free(DynBuffer *buf) {
(void)buf;
}
Allocating sizeof(DynBuffer*) instead of sizeof(DynBuffer) + capacity; forgetting data offset.
Appending more than capacity returns -1 without buffer modification; capacity == 0 creates empty buffer.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.