Skip to content

Instantly share code, notes, and snippets.

@emersion
Last active July 15, 2018 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emersion/ea7595f63b1d0fb9d4a8cfcda4ee9490 to your computer and use it in GitHub Desktop.
Save emersion/ea7595f63b1d0fb9d4a8cfcda4ee9490 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct my_array {
void *data;
size_t cap;
size_t len, elem_size;
};
void my_array_init(struct my_array *array, size_t elem_size) {
memset(array, 0, sizeof(struct my_array));
array->elem_size = elem_size;
}
void *my_array_grow(struct my_array *array, size_t n) {
size_t size = array->len * array->elem_size;
assert(size <= array->cap);
size_t new_len = array->len + n;
size_t new_size = size + n * array->elem_size;
size_t new_cap = array->cap;
if (new_cap == 0) {
new_cap = 16;
}
while (new_size > new_cap) {
new_cap *= 2;
}
if (array->cap < new_cap) {
void *new_data = realloc(array->data, new_cap);
if (new_data == NULL) {
return NULL;
}
array->data = new_data;
array->cap = new_cap;
}
void *ptr = (char *)array->data + size;
array->len = new_len;
return ptr;
}
void my_array_add(struct my_array *array, void *value) {
void *ptr = my_array_grow(array, 1);
if (ptr == NULL) {
return;
}
memcpy(ptr, value, array->elem_size);
}
void my_array_add_array(struct my_array *array, void *src, size_t n) {
void *ptr = my_array_grow(array, n);
memcpy(ptr, src, n * array->elem_size);
}
void my_array_finish(struct my_array *array) {
free(array->data);
}
void main() {
struct my_array a = {0};
my_array_init(&a, sizeof(int));
int v = 0;
my_array_add(&a, &v);
v = 1;
my_array_add(&a, &v);
v = 42;
my_array_add(&a, &v);
int *values = a.data;
for (size_t i = 0; i < a.len; ++i) {
printf("%d\n", values[i]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment