Created
August 21, 2018 02:54
-
-
Save parkj90/ccd403f06a04bebe6daf8272621e4ef9 to your computer and use it in GitHub Desktop.
dynamic array with void pointer
This file contains 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.
Learn more about bidirectional Unicode characters
//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); | |
} | |
} |
This file contains 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.
Learn more about bidirectional Unicode characters
//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 *)); |
This file contains 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.
Learn more about bidirectional Unicode characters
//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