August 11, 2022

SoftwareSplash.com

Latest Software News and Hacks

Finally made a dynamic array library

tldr; this isn’t meant for people to actually use it was merely a learning exercise .

Id appreciate any feedback on the code. I am still learning and want to iron out any bad habits.

#include <stdio.h> #include <stdlib.h> #include <string.h> typedef enum { AR_UNASSIGNED, AR_INT, AR_STRING, AR_COUNT } ArrType; // Parent class typedef struct { char *name[32]; ArrType type; size_t length; size_t capacity; } ArrHead; // Child classes typedef struct { ArrHead head; int *arr; } ArrInt; typedef struct { ArrHead head; char **arr; } ArrString; // debug macros #define DEBUG 1 #define log(MSG) printf("log: "MSG"n") #define err(MSG) fprintf(stderr, "error in line %d: "MSG"n", __LINE__) // Init functions /* * Note: to successfully call array_create(), you must assign * typing to your data structure. e.g. * ``` * ArrInt arr; * arr.head.type = AR_INT; * ... * ``` * */ extern void array_create(ArrHead *head, size_t size); extern void array_destroy(ArrHead *head); // Array functions extern void array_append(ArrHead *head, const void *item); extern void array_pop(ArrHead *head); extern void array_remove_index(ArrHead *head, size_t index); extern void array_replace_index(ArrHead *head, size_t index, const void *item); // Informative functions extern void array_print(ArrHead *head); void array_create(ArrHead *head, size_t size) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; array->arr = malloc(sizeof(int) * size); if (array->arr == NULL) { err("malloc failed"); exit(1); } head->length = 0; head->capacity = size; #ifdef DEBUG log("integer array created"); #endif } else if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; array->arr = malloc(sizeof(char *) * size); if (array->arr == NULL) { err("malloc failed"); exit(1); } /* * To avoid undefined behaviour we set malloc enough * for one char. * */ for (size_t i = 0; i < size; i++) { array->arr[i] = malloc(sizeof(char)); if (array->arr[i] == NULL) { err("malloc failed"); exit(1); } } head->length = 0; head->capacity = size; #ifdef DEBUG log("string array created"); #endif } else if (head->type == AR_UNASSIGNED) { err("Unassigned typing to array, assign `array_struct`.head.type enum"); } } // Macro to set default length of array #define array_create(A) array_create(A, 8) void array_destroy(ArrHead *head) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; free(array->arr); #ifdef DEBUG log("integer array destroyed"); #endif } else if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; for (size_t i = 0; i < head->capacity; i++) free(array->arr[i]); free(array->arr); #ifdef DEBUG log("string array destroyed"); #endif } } void array_append(ArrHead *head, const void *item) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; // dynamic resize if ((head->capacity - head->length) <= 0) { head->capacity *= 2; int *data = realloc(array->arr, sizeof(int) * head->capacity); if (data == NULL) { err("realloc failed"); exit(1); } array->arr = data; } // appending item int casted = (int)item; array->arr[head->length] = casted; head->length++; } if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; // cast head for child // dynamic resize if ((head->capacity - head->length) <= 0) { head->capacity *= 2; char **data = realloc(array->arr, sizeof(char *) * head->capacity); if (data == NULL) { err("realloc failed"); exit(1); } array->arr = data; } // appending item char *casted = (char *)item; size_t str_len; for (str_len = 0; casted[str_len] != ''; ++str_len); char *data = realloc(array->arr[head->length], sizeof(char) * ++str_len); array->arr[head->length] = data; memcpy(array->arr[head->length], casted, str_len * sizeof(char)); head->length++; } } void array_pop(ArrHead *head) { head->length--; } void array_remove_index(ArrHead *head, size_t index) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; while ((index + 1) < (head->length)) { (array->arr)[index] = (array->arr)[index + 1]; ++index; } head->length--; } else if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; while ((index + 1) < (head->length)) { size_t str_len; for (str_len = 0; array->arr[index + 1][str_len] != ''; ++str_len); char *data = realloc(array->arr[index], sizeof(char) * ++str_len); if (data == NULL) { err("realloc failed"); exit(1); } memcpy(array->arr[index], array->arr[index + 1], str_len); ++index; } head->length--; } } void array_replace_index(ArrHead *head, size_t index, const void *item) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; array->arr[index] = (int)item; } else if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; char *str = (char *)item; size_t str_len; for (str_len = 0; str[str_len] != ''; ++str_len); char *data = realloc(array->arr[index], sizeof(char) * ++str_len); if (data == NULL) { err("realloc failed"); exit(1); } array->arr[index] = data; memcpy(array->arr[index], item, str_len); } } void array_print(ArrHead *head) { if (head->type == AR_INT) { ArrInt *array = (ArrInt *)head; printf("["); for (size_t i = 0; i < head->length - 1; ++i) printf("%d, ", array->arr[i]); printf("%d]n", array->arr[head->length - 1]); } else if (head->type == AR_STRING) { ArrString *array = (ArrString *)head; printf("["); for (size_t i = 0; i < head->length - 1; ++i) printf("%s, ", array->arr[i]); printf("%s]n", array->arr[head->length - 1]); } } 

submitted by /u/Snoo_71497
[link] [comments]


Go to Source of this post
Author Of this post: /u/Snoo_71497
Title Of post: Finally made a dynamic array library
Author Link: {authorlink}