C Dynamic Array Project
Implement a small owned vector with length, capacity and failure-aware geometric growth.
Your brief
Create a resizable sequence without reallocating on every insertion. Track used length separately from allocated capacity. When full, double the capacity only after checking both capacity arithmetic and byte-size multiplication. Leave the vector unchanged if growth fails. The worked solution starts empty, accepts five values and releases the allocation at the end. The interface is private to this example and requires a valid initialized vector object; a reusable module should expose initialization, destruction and borrowing rules explicitly.
Run it locally
Use a hosted C17 compiler in a separate lab folder. The command assumes a driver named cc; substitute gcc, clang or zig cc as appropriate. C does not currently run in Bhylu’s browser playground. Apache, PHP and MySQL are not needed for these C programs.
cc -std=c17 -Wall -Wextra -Wpedantic -Werror vector-project.c -o lessonOn Windows, use -o lesson.exe and run .\lesson.exe in PowerShell. On Unix-like systems run ./lesson. Math-library linking differs by toolchain; GCC on many Unix systems needs -lm after the source.
Download the complete C source. File-writing labs must run in an empty private directory, away from existing reports.
Worked solution
Show the worked solution
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
struct Vector { int *data; size_t used; size_t capacity; };
static bool append(struct Vector *v, int value) {
if (v->used == v->capacity) {
if (v->capacity > SIZE_MAX / 2) { return false; }
size_t next = v->capacity == 0 ? 2 : v->capacity * 2;
if (next > SIZE_MAX / sizeof *v->data) { return false; }
int *grown = realloc(v->data, next * sizeof *v->data);
if (grown == NULL) { return false; }
v->data = grown; v->capacity = next;
}
v->data[v->used++] = value;
return true;
}
int main(void) {
struct Vector vector = {NULL, 0, 0};
for (int value = 10; value <= 14; ++value) {
if (!append(&vector, value)) { free(vector.data); return 1; }
}
printf("Used: %zu; capacity: %zu; last: %d\n", vector.used, vector.capacity, vector.data[vector.used - 1]);
free(vector.data);
return 0;
}
Expected result
Used: 5; capacity: 8; last: 14
The capacities progress from two to four to eight, so five values fit without five separate reallocations. realloc with a null initial pointer behaves like an allocation for this nonzero size. A successful growth invalidates earlier borrowed element pointers. The review executes the ordinary growth path; it does not claim exhaustive allocator-failure injection or a thread-safe container.
Extend and test
Add a pop operation that reports empty separately from a valid value. Add an explicit maximum record count and test growth exactly at a capacity boundary.
For language and library rules, consult the WG14 C working group and its public C11 committee draft, which describes the core facilities used here; C17 incorporates corrections. Check your compiler and runtime documentation for implementation details.