Skip to content

Instantly share code, notes, and snippets.

@MinecraftPublisher
Created February 14, 2024 09:00
Show Gist options
  • Select an option

  • Save MinecraftPublisher/78b43fb0a4f93d142dd6066802bd6a04 to your computer and use it in GitHub Desktop.

Select an option

Save MinecraftPublisher/78b43fb0a4f93d142dd6066802bd6a04 to your computer and use it in GitHub Desktop.
Dynamic arrays in C

list.h: dynamic arrays in c

simple header file for dynamic arrays that you can include in your code.

properties:

  • TYPE string: char*
  • TYPE byte: unsigned char
  • TYPE bool: byte (unsigned char)
  • TYPE ull: unsigned long long
  • MACRO CAT(x, y): Adds two words together. Used for building function names.
  • MACRO sanity(var): Calls memoryFailure if the variable is NULL.
  • MACRO zmalloc(size): Allocates memory with safety checks in place.
  • MACRO zrealloc(ptr, size): Reallocates memory with safety checks in place.
  • MACRO __create_primitive(type, lname): Creates a dynamic array type with a custom name.
  • MACRO __create_list_type(type): Creates a dynamic array type with the name of {type}_list.
  • FUNCTION memoryFailure(file, line): Prints a notice and exits. To be used with sanity.

list type properties:

  • TYPE {type}_list: Struct with ull size and type *arr.
  • FUNCTION create_{type}_list(): Creates a dynamic list.
  • FUNCTION push_{type}_list({type}_list *list, type item): Pushes an item to the end of the array.
  • FUNCTION append_{type}_list({type}_list *list, ull index, type value): Pushes an item to a specified index of the array.
  • FUNCTION remove_{type}_list({type}_list *list, ull index): Removes an item from a specified index of the array.
#include <stdio.h>
#include <stdlib.h>
#define P_CAT(x, y) x##y
#define CAT(x, y) P_CAT(x, y)
typedef char *string;
typedef unsigned char byte;
typedef byte bool;
void memoryFailure(string file, int line) {
printf("Memory allocation failure!\nAt file %s\nLine %i\n", file, line);
exit(SIGABRT);
}
// sanity check for memory failures
#define sanity(x) \
({ \
if (x == NULL) memoryFailure(__FILE__, __LINE__); \
})
#define zmalloc(size) \
({ \
void *data = malloc(size); \
sanity(data); \
data; \
})
#define zrealloc(ptr, size) \
({ \
void *data = realloc(ptr, size); \
sanity(data); \
data; \
})
typedef unsigned long long ull;
#define __create_primitive(type, lname) \
typedef struct lname { \
ull size; \
type *arr; \
} lname; \
\
lname *CAT(create_, lname)() { \
lname *ptr = zmalloc(sizeof(lname)); \
ptr->size = 1; \
ptr->arr = zmalloc(sizeof(type)); \
return ptr; \
} \
\
lname *CAT(push_, lname)(lname * list, type item) { \
list->size++; \
list->arr = zrealloc(list->arr, sizeof(type) * list->size); \
list->arr[ list->size - 2 ] = item; \
return list; \
} \
\
lname *CAT(append_, lname)(lname * list, ull index, type value) { \
list->size++; \
type *new_ptr = zmalloc(sizeof(type) * list->size); \
ull exp = 0; \
for (ull i = 0; i < list->size; i++) \
if (i != index) new_ptr[ exp++ ] = list->arr[ i ]; \
else \
new_ptr[ exp++ ] = value; \
free(list->arr); \
list->arr = new_ptr; \
return list; \
} \
\
lname *CAT(remove_, lname)(lname * list, ull index) { \
list->size--; \
type *new_ptr = zmalloc(sizeof(type) * list->size); \
ull exp = 0; \
for (ull i = 0; i < list->size; i++) \
if (i != index) new_ptr[ exp++ ] = list->arr[ i ]; \
free(list->arr); \
list->arr = new_ptr; \
return list; \
}
#define __create_list_type(type) __create_primitive(type, CAT(type, _list))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment