A generic dynamic array in C that stores no capacity and needs no struct

alurm1 pts0 comments

A generic dynamic array in C that stores no capacity and needs no struct · GitHub

/" data-turbo-transient="true" />

Skip to content

-->

Search Gists

Search Gists

Sign in

Sign up

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

Instantly share code, notes, and snippets.

alurm/README.md

Last active<br>June 13, 2026 02:39

Show Gist options

Download ZIP

Star

(0)

You must be signed in to star a gist

Fork

(0)

You must be signed in to fork a gist

Embed

Select an option

Embed<br>Embed this gist in your website.

Share<br>Copy sharable link for this gist.

Clone via HTTPS<br>Clone using the web URL.

No results found

Learn more about clone URLs

Clone this repository at &lt;script src=&quot;https://gist.github.com/alurm/2ca14be134d719fe7431217a6b18d91e.js&quot;&gt;&lt;/script&gt;

" readonly="readonly" data-autoselect="true" data-target="primer-text-field.inputElement " aria-describedby="validation-a6367f92-0567-47c9-8488-319dd3a5d611" class="form-control FormControl-monospace FormControl-input FormControl-small rounded-left-0 rounded-right-0 border-right-0" type="text" name="gist-share-url-sized-down" />

Save alurm/2ca14be134d719fe7431217a6b18d91e to your computer and use it in GitHub Desktop.

Embed

Select an option

Embed<br>Embed this gist in your website.

Share<br>Copy sharable link for this gist.

Clone via HTTPS<br>Clone using the web URL.

No results found

Learn more about clone URLs

Clone this repository at &lt;script src=&quot;https://gist.github.com/alurm/2ca14be134d719fe7431217a6b18d91e.js&quot;&gt;&lt;/script&gt;

" readonly="readonly" data-autoselect="true" data-target="primer-text-field.inputElement " aria-describedby="validation-30513451-d684-4413-9cde-39df9ce0558a" class="form-control FormControl-monospace FormControl-input FormControl-small rounded-left-0 rounded-right-0 border-right-0" type="text" name="gist-share-url-original" />

Save alurm/2ca14be134d719fe7431217a6b18d91e to your computer and use it in GitHub Desktop.

Download ZIP

A generic dynamic array in C that stores no capacity and needs no struct

Raw

README.md

A generic dynamic array in C that stores no capacity and needs no struct

The following header shows a way to make a generic dynamic array in C with an array of two pointers:

the first pointer stores the length of the dynamic array;

the second pointer points to the data.

So, int *vec[2] = { 0 }; is an empty dynamic array of ints. struct person *people[2] = { 0 }; is an empty dynamic array of people.

(uintptr_t)vec[0] is the length of the array, vec[1] is the array.

The vec_push macro pushes a value at the end of the dynamic array and returns true on success.

This code is C23 with statement expressions (a GNU C feature).

Why is this interesting

First of all, structs aren't used so you don't have to invent names for them (e.g. there is no IntVec). Since a pointer is used to store the length of the dynamic array (as a uintptr_t), this relies on implementation-defined behavior, that is the uintptr_t length read from a pointer must be the same length that was stored.

Second of all, capacity isn't stored at all. Instead, it's computed on demand when the length of the vec is either zero or a power of two. In this case realloc is called with capacity equal to the next power of two greater than the length. The drawback is that it's more difficult to "reserve" elements: during pushing, when the length reaches a power of two, realloc is called for the next power of two no matter what, so a larger manual reservation is effectively discarded.

Raw

main.c

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.<br>Learn more about bidirectional Unicode characters

Show hidden characters

#include

#include "vec.h"

int main() {

int *ints[2] = { 0 };

for (uintptr_t i = 0; i 5; i++) if (!vec_push(ints, i + 42)) {

return 1;

// 42, 43, 44, 45, 46.

for (uintptr_t i = 0; i (uintptr_t)ints[0]; i++) printf("%d\n", ints[1][i]);

// Shrinking works.

ints[0] = (void *)3;

// You can only reclaim memory down to the next power of two greater than or equal to the length.

// Otherwise pushing will break.

ints[1] = realloc(ints[1], sizeof(**ints) * 4);

// 42, 43, 44.

for (uintptr_t i = 0; i (uintptr_t)ints[0]; i++) printf("%d\n", ints[1][i]);

free(ints[1]);

struct person {

char *name;

int age;

} *people[2] = { 0 };

vec_push(people, ((struct person){ "Bob", 21 }));

vec_push(people, ((struct person){ "Joe", 42 }));

// Bob: 21, Joe: 42.

for (uintptr_t i = 0; i (uintptr_t)people[0]; i++) printf("%s: %d\n", people[1][i].name, people[1][i].age);

free(people[1]);

Raw

vec.h

This file contains hidden or bidirectional Unicode...

array ints gist dynamic uintptr_t length

Related Articles