Skip to content

Instantly share code, notes, and snippets.

@parkj90
Created August 21, 2018 02:54
Show Gist options
  • Save parkj90/ccd403f06a04bebe6daf8272621e4ef9 to your computer and use it in GitHub Desktop.
Save parkj90/ccd403f06a04bebe6daf8272621e4ef9 to your computer and use it in GitHub Desktop.
dynamic array with void pointer
//array.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "array.h"
array_t *array_new(void) {
array_t *array = malloc(sizeof(array_t));
if (!array) {
return NULL;
}
array->size = 0;
array->data_elements = NULL;
return array;
}
int array_get(array_t *array, unsigned int index, void *value, size_t size) {
if (array == NULL || index >= array->size || size < (array->data_elements + index)->size) {
return -1;
}
char *array_data = (array->data_elements + index)->data;
char *destination_ptr = value;
for (size_t i = 0; i < (array->data_elements + index)->size; i++) {
destination_ptr[i] = array_data[i];
}
return 0;
}
int array_set(array_t *array, unsigned int index, void *value, size_t size) {
if (array == NULL || index >= array->size) {
return -1;
}
if (value == NULL) {
(array->data_elements + index)->data = NULL;
(array->data_elements + index)->size = 0;
} else {
char *array_data = malloc(size * sizeof(char));
if (array_data == NULL) {
return -2;
}
free((array->data_elements + index)->data);
(array->data_elements + index)->data = array_data;
(array->data_elements + index)->size = size;
char *incoming_data = value;
for (size_t i = 0; i < size; i++) {
array_data[i] = incoming_data[i];
}
}
return 0;
}
int array_append(array_t *array, void *value, size_t size) {
if (array == NULL) {
return -1;
}
data_element_t *temp = realloc(array->data_elements, (array->size + 1) * sizeof(data_element_t));
if (temp == NULL) {
return -2;
}
if (value == NULL) {
(array->data_elements + array->size)->data = NULL;
(array->data_elements + array->size)->size = 0;
} else {
char *array_data = malloc(size * sizeof(char));
if (array_data == NULL) {
return -2;
}
char *incoming_data = value;
for (size_t i = 0; i < size; i++) {
array_data[i] = incoming_data[i];
}
(temp + array->size)->data = array_data;
(temp + array->size)->size = size;
}
array->data_elements = temp;
array->size++;
return 0;
}
int array_delete(array_t *array, unsigned int index) {
if (array == NULL || index >= array->size) {
return -1;
}
data_element_t last = *(array->data_elements + (array->size - 1));
data_element_t *temp = realloc(array->data_elements, (array->size - 1) * sizeof(data_element_t));
if (temp == NULL) {
return -2;
}
array->data_elements = temp;
array->size--;
//free data pointer in indexed data_element
if (index < array->size) {
free((array->data_elements + index)->data);
} else {
free(last.data);
}
if (index < array->size - 1) {
memmove(array->data_elements + index, array->data_elements + index + 1, (array->size - index - 1) * sizeof(data_element_t));
}
if (index < array->size) {
*(array->data_elements + (array->size - 1)) = last;
}
return 0;
}
unsigned int array_length(array_t *array) {
if (array == NULL) {
return -1;
}
return array->size;
}
void array_free(array_t *array) {
if (array == NULL) {
return;
}
for (int i = 0; i < array->size; i++) {
free((array->data_elements + i)->data);
}
free(array->data_elements);
free(array);
}
void array_traverse(array_t *array, void (*f)(void *)) {
if (array == NULL) {
return;
}
for (int i = 0; i < array->size; i++) {
f((array->data_elements + i)->data);
}
}
//array.h
typedef struct {
size_t size;
void *data;
}data_element_t;
typedef struct {
unsigned int size;
data_element_t *data_elements;
} array_t;
array_t *array_new(void);
int array_get(array_t *array, unsigned int index, void *value, size_t size);
int array_set(array_t *array, unsigned int index, void *value, size_t size);
int array_append(array_t *array, void *value, size_t size);
int array_delete(array_t *array, unsigned int index);
unsigned int array_length(array_t *array);
void array_free(array_t *array);
void array_traverse(array_t *array, void (*f)(void *));
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "array.h"
static void print(void *value);
int main(void) {
array_t *d_array = array_new();
if (d_array == NULL) {
printf("failed to allocate array\n");
return -1;
}
char *value = malloc(20 * sizeof(char));
//test append
assert(array_append(d_array, (char []) {"hello world"}, 12) == 0);
assert(array_append(d_array, (char []) {"foo"}, 4) == 0);
assert(array_append(d_array, (char []) {"bar"}, 4) == 0);
//test delete
assert(array_delete(d_array, 1) == 0);
//test get
assert(array_get(d_array, 0, value, 20) == 0);
printf("should print hello world: %s\n", value);
//test set
assert(array_set(d_array, 1, (char[]){"abcd"}, 5) == 0);
assert(array_get(d_array, 1, value, 20) == 0);
printf("should print abcd: %s\n", value);
//test length
assert(array_length(d_array) == 2);
//test traverse
array_traverse(d_array, print);
array_free(d_array);
free(value);
return 0;
}
static void print(void *value) {
printf("%s\n", value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment