A Reusable Vector Type
Wrap size and capacity.
A Reusable Vector Type is a free C Academy lesson on CoddyKit. This is lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C Academy learning path, and your progress syncs across the web and the CoddyKit app. The C Academy course includes 4 lessons in total.
From Loose Code to a Type
Passing around a pointer, a count, and a capacity as three separate variables is error-prone.
Let's bundle them into one struct: a reusable dynamic array, often called a vector. It packages the data and the bookkeeping together.
The Vector Struct
A vector needs three fields: a pointer to the data, how many elements are used (len), and how many fit before resizing (cap).
typedef struct {
int *data;
size_t len;
size_t cap;
} Vec;Initializing a Vector
An empty vector has a NULL data pointer and zero length and capacity. A small init function makes the intent clear.
void vec_init(Vec *v) {
v->data = NULL;
v->len = 0;
v->cap = 0;
}The Push Operation
vec_push adds one element to the end. If the vector is full, it doubles the capacity first.
It returns 0 on success and -1 if allocation fails, so callers can react.
int vec_push(Vec *v, int value) {
if (v->len == v->cap) {
size_t nc = v->cap ? v->cap * 2 : 4;
int *tmp = realloc(v->data, nc * sizeof(*v->data));
if (!tmp) return -1;
v->data = tmp;
v->cap = nc;
}
v->data[v->len++] = value;
return 0;
}Reading Elements Back
Because len tracks the used count, you iterate from 0 to len - 1. The capacity may be larger, but those slots aren't part of your data yet.
for (size_t i = 0; i < v->len; i++)
printf("%d\n", v->data[i]);Freeing the Vector
A vector owns its heap buffer, so it needs a matching cleanup function. After freeing, reset the fields so the struct can't be misused.
void vec_free(Vec *v) {
free(v->data);
v->data = NULL;
v->len = v->cap = 0;
}Putting It Together
This full program builds a vector, pushes five values, prints them, then frees it cleanly.
#include <stdio.h>
#include <stdlib.h>
typedef struct { int *data; size_t len, cap; } Vec;
int vec_push(Vec *v, int value) {
if (v->len == v->cap) {
size_t nc = v->cap ? v->cap * 2 : 4;
int *tmp = realloc(v->data, nc * sizeof(*v->data));
if (!tmp) return -1;
v->data = tmp; v->cap = nc;
}
v->data[v->len++] = value;
return 0;
}
int main(void) {
Vec v = {0};
for (int i = 0; i < 5; i++) vec_push(&v, i * 10);
for (size_t i = 0; i < v.len; i++) printf("%d\n", v.data[i]);
free(v.data);
return 0;
}Zero-Initializing with {0}
Writing Vec v = {0}; sets every field to zero, including the data pointer to NULL.
This is a handy shortcut that makes a vector ready for vec_push without calling an explicit init function.
Vec v = {0}; /* data=NULL, len=0, cap=0 */
vec_push(&v, 42);A Safe get Helper
Indexing past len is a bug. A small accessor can check bounds and signal errors, trading a little speed for safety.
int vec_get(const Vec *v, size_t i, int *out) {
if (i >= v->len) return -1; /* out of range */
*out = v->data[i];
return 0;
}Why Track len and cap Separately
cap is how much memory is allocated; len is how much you actually use.
Keeping spare capacity means most pushes don't call realloc. This separation is what makes a vector both fast and flexible.
Generalizing the Type
This vector stores int. To hold other types you can change the element type, or store void * with an element size.
The pattern, init, push, free, stays the same regardless of what you store.
typedef struct {
double *data;
size_t len, cap;
} DVec; /* same shape, different element type */Quick Check
Test your understanding of the vector type.
Recap
A vector bundles a data pointer, len, and cap into one struct.
vec_push doubles capacity when full, vec_free releases the buffer and resets fields, and {0} initializes cleanly. This reusable pattern beats juggling loose variables. Next: freeing correctly and avoiding leaks.
Learn C with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 39
- Lessons
- 144
Frequently Asked Questions
Is the “A Reusable Vector Type” lesson free?
Yes — the full text of “A Reusable Vector Type” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C Academy course, upgrade to CoddyKit PRO. The C Academy course includes 4 lessons in total.
What will I learn in “A Reusable Vector Type”?
Wrap size and capacity. You practise C Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C Academy?
No prior experience is required. C Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “A Reusable Vector Type” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C Academy lesson?
Yes. Every C Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Allocating an Array
- Growing with realloc
- A Reusable Vector Type
- Freeing and Avoiding Leaks