diff --git a/linked_lists/queue.c b/linked_lists/queue.c index 675c3ca..db5448c 100644 --- a/linked_lists/queue.c +++ b/linked_lists/queue.c @@ -191,7 +191,7 @@ int clear_queue_data(queue_t **queue, void (*free_func)()) { /* This function serializes the queue. */ /* Note that it'll return NULL on allocation failure or invalid input - in the former case it'll set the correct length in the specified pointer, in the second it will set -1. */ -void **serialize_queue(queue_t *queue, int *length) { +void *serialize_queue(queue_t *queue, int *length) { /* Sanity check. */ if (!queue) { *length = -1; diff --git a/linked_lists/queue.h b/linked_lists/queue.h index 8dfd852..2651323 100644 --- a/linked_lists/queue.h +++ b/linked_lists/queue.h @@ -55,6 +55,6 @@ int clear_queue(queue_t **queue); /* This function deletes all the nodes of the given queue. */ int clear_queue_data(queue_t **queue, void (*free_function)()); /* This function serializes the queue. */ -void **serialize_queue(queue_t *queue, int *length); +void *serialize_queue(queue_t *queue, int *length); #endif /* QUEUE_H */ diff --git a/linked_lists/single_linked_list.c b/linked_lists/single_linked_list.c index af57874..4850c3e 100644 --- a/linked_lists/single_linked_list.c +++ b/linked_lists/single_linked_list.c @@ -14,6 +14,8 @@ * along with this program. If not, see . */ +/* TODO: fixing serialization: change the code to take a user-supplied indexing function and array, and just send the current void pointer to it with the index in each iteration of the loop. */ + /* This file contains the function implementations for single linked lists. */ /* Include guard + includes. */ #ifndef SINGLE_LINKED_LIST_C @@ -21,8 +23,8 @@ #include "single_linked_list.h" #endif /* SINGLE_LINKED_LIST_C */ -/* This function initializes a new linked list, returns NULL on failure. */ -linked_list_t* initialize_single_linked_list() { +/* This function initializes a new linked list, returns NULL on failure - data_size is used for storing stored object size. */ +linked_list_t* initialize_single_linked_list(size_t data_size) { /* Variables. */ linked_list_t *result; @@ -36,6 +38,7 @@ linked_list_t* initialize_single_linked_list() { /* Initialize the internal fields. */ result->length = 0; result->head = NULL; + result->data_size = data_size; /* Return the result. */ return result; @@ -448,10 +451,11 @@ int clear_list_data_single_linked_list(linked_list_t **list, void (*free_functio /* This function attetmps to serialize a linked list into an array. */ /* The function will allocate and return a pointer to said array on success, NULL on failure. */ -/* The length of the array is sent through the length pointer, and set to -1 on failure. */ -void **serialize_linked_list(linked_list_t *list, int *length) { +/* The length of the array is sent through the length pointer, and set to 0 on failure. */ +static inline void *serialize_linked_list(linked_list_t *list, size_t *length) { /* Local variables. */ - void **array; + void *array; + char *buffer; node_t *current; int i; @@ -462,17 +466,27 @@ void **serialize_linked_list(linked_list_t *list, int *length) { /* Set the length. */ *length = list->length; /* Attempt to allocate the array. */ - array = (void**) malloc((*length) * sizeof(void*)); + array = (void*) malloc((*length) * (list->data_size)); /* Check for allocation failure. */ if (array == NULL) { - *length = -1; + *length = 0; + return NULL; + } + /* Attempt to allocate the buffer. */ + buffer = (char*) malloc(list->data_size); + if (buffer == NULL) { + *length = 0; return NULL; } /* Fill the array. */ current = list->head; for (i = 0; i < *length; i++) { - array[i] = current->data; + /* Attempt to copy to the current buffer. */ + memcpy(buffer, (char*)current->data, list->data_size); + /* Copy the data for the current item. */ + /*memcpy(array + (i * list->data_size), current->data, list->data_size);*/ + /* Advance the pointer. */ current = current->next; } diff --git a/linked_lists/single_linked_list.h b/linked_lists/single_linked_list.h index 8a6d898..cc0c39e 100644 --- a/linked_lists/single_linked_list.h +++ b/linked_lists/single_linked_list.h @@ -17,6 +17,7 @@ /* This header defines a single-linked-list and related functions. */ /* Use the single nodes. */ #include /* Used in allocations and deallocations. */ +#include /* For using memcpy. */ #ifndef SINGLE_LINKED_LIST_H #define SINGLE_LINKED_LIST_H #include "../nodes/single_node.h" @@ -41,10 +42,12 @@ typedef struct linked_list { int length; /* Stores the head node pointer. */ node_t *head; + /* The size of each of the data values. */ + size_t data_size; } linked_list_t; /* This function initializes a new linked list. */ -linked_list_t* initialize_single_linked_list(); +linked_list_t* initialize_single_linked_list(size_t data_size); /* This function appends a node to the given linked list. */ int append_node_single_linked_list(linked_list_t *list, node_t *node); /* This function prepends a node to the given linked list. */ @@ -90,5 +93,5 @@ int clear_list_single_linked_list(linked_list_t **list); /* This function deletes all the nodes and data stored within of the given list and the list itself. */ int clear_list_data_single_linked_list(linked_list_t **list, void (*free_function)(void*)); /* This function attempts to serialize a linked list into an array. */ -void **serialize_linked_list(linked_list_t *list, int *length); +static inline void *serialize_linked_list(linked_list_t *list, size_t *length); #endif /* SINGLE_LINKED_LIST_H */ diff --git a/tests/makefile b/tests/makefile index 8bc3a7b..2dd1f48 100644 --- a/tests/makefile +++ b/tests/makefile @@ -16,14 +16,20 @@ bubble_sort_tests.o: bubble_sort_tests.c double_linked_list_tests.out: double_linked_list_tests.c gcc -g -fsanitize=address -fsanitize=leak -fsanitize=undefined double_linked_list_tests.c -o double_linked_list_tests.out -queue_tests.out: queue_tests.c - gcc -g -I ../linked_lists/ -fsanitize=address -fsanitize=leak -fsanitize=undefined queue_tests.c -o queue_tests.out +single_linked_list.o: ../linked_lists/single_linked_list.h ../linked_lists/single_linked_list.c + gcc -g -c ../linked_lists/single_linked_list.c -o single_linked_list.o + +queue_tests.o: queue_tests.c + gcc -g -c -fanalyzer -fsanitize=address -fsanitize=leak -fsanitize=undefined queue_tests.c -o queue_tests.o + +queue_tests.out: queue_tests.o single_linked_list.o + gcc -g -fsanitize=address -fsanitize=leak -fsanitize=undefined single_linked_list.o queue_tests.o -o queue_tests.out quick_sort_tests.out: array_print.o quick_sort_tests.o gcc -g -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries -fsanitize=address -fsanitize=leak -fsanitize=undefined array_print.o quick_sort_tests.o -o quick_sort_tests.out quick_sort_tests.o: quick_sort_tests.c - gcc -g -D DEBUG -c -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries quick_sort_tests.c + gcc -g -D DEBUG -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries -c quick_sort_tests.c array_print.o: ../utils/array_print.c gcc -g -c ../utils/array_print.c diff --git a/tests/single_linked_list_tests.c b/tests/single_linked_list_tests.c index 912463d..1a69c37 100644 --- a/tests/single_linked_list_tests.c +++ b/tests/single_linked_list_tests.c @@ -66,7 +66,7 @@ linked_list_t* generate_long_random_list(int length) { int i; /* Allocate the list. */ - list = initialize_single_linked_list(); + list = initialize_single_linked_list(sizeof(int)); if (list == NULL) return NULL; @@ -119,15 +119,16 @@ int list_count_length(linked_list_t *list) { /* This function attempts to allocate a list, fill it, then serialize it. */ int test_serialization() { /* Local variables. */ - int i, length; + int i; + size_t length; /* Used to allocate and store a value. */ int *value; /* Used to store the array. */ - void **array; + void *array; /* Allocations. */ /* Initialize the list. */ - linked_list_t *list = initialize_single_linked_list(); + linked_list_t *list = initialize_single_linked_list(sizeof(int)); if (list == NULL) { return 1; } @@ -164,7 +165,9 @@ int test_serialization() { /* Check the values. */ for (i = 0; i < SERIALIZATION_TEST_LIST_LENGTH; i++) { - if (*((int *)(array[i])) != i) { + /* Get the value. */ + *value = *((int *)(array + (i * sizeof(int)))); + if (*value != i) { /* Clear the list. */ clear_list_data_single_linked_list(&list, NULL); /* Free the array. */ @@ -191,7 +194,7 @@ int test_linked_lists() { int error; /* Initialize an empty list. */ - list = initialize_single_linked_list(); + list = initialize_single_linked_list(sizeof(int)); /* Check that it was correctly created. */ assert(list != NULL); assert(list->length == INITIAL_LIST_LENGTH);