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
#include <stdlib.h> | |
#include <time.h> | |
#include <stdio.h> | |
#include <math.h> | |
#include "dynarray.h" | |
int main(int argc, char **argv) { | |
// The array | |
dynarray_t array; | |
// The current index in the array | |
int index; | |
// Seed the random number generator with the current time | |
srand(time(NULL)); | |
// Initialize the array with 8 elements | |
if (!dynarray_init(&array, 8)) { | |
printf("Failed to initialize array\n"); | |
return EXIT_FAILURE; | |
} | |
// Allocate memory for the value to be stored in the array | |
int *value = malloc(sizeof(int)); | |
// Add 10 elements to the array | |
for (index = 0; index < 10; index++) { | |
// Assign the value to be stored in the array | |
*value = rand() % 100; | |
// Add the element to the array | |
if (!dynarray_add(&array, value)) { | |
printf("Failed to add element %d to array\n", index); | |
// Free all elements in the array | |
dynarray_deep_free(&array); | |
// Free the value | |
free(value); | |
return EXIT_FAILURE; | |
} | |
// Allocate memory for the next value | |
value = malloc(sizeof(int)); | |
} | |
// Assign the value to be stored in the array | |
*value = 9999; | |
// Set the first element | |
if (!dynarray_set(&array, 0, value)) { | |
printf("Failed to set element 0 in array\n"); | |
// Free all elements in the array | |
dynarray_deep_free(&array); | |
// Free the value | |
free(value); | |
return EXIT_FAILURE; | |
} | |
// The size of the array | |
int size = array.size; | |
// Iterate the elements in the array | |
for (index = 0; index < size; index++) { | |
// Retrieve the current element of the array | |
if (!dynarray_get(&array, index, (void **) &value)) { | |
printf("Failed to retrieve element %d from the array\n", index); | |
// Free all elements in the array | |
dynarray_deep_free(&array); | |
return EXIT_FAILURE; | |
} | |
// Output the current element | |
printf("[%2d] = %2d\n", index, *value); | |
} | |
// Output information about the array | |
printf("Current size: %d elements\n", array.size); | |
printf("Current capacity: %d elements\n", array.capacity); | |
printf("Initial capacity: %d elements\n", array.initial_capacity); | |
printf("Resized %d times\n", (int) floor(log(array.capacity / array.initial_capacity) / log(2))); | |
// Free all elements in the array | |
dynarray_deep_free(&array); | |
return EXIT_SUCCESS; | |
} |
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
/* | |
dynarray - Simple dynamically sized C arrays. | |
Copyright (C) 2015 Jack Wilsdon | |
This program is free software: you can redistribute it and/or modify | |
it under the terms of the GNU Affero General Public License as | |
published by the Free Software Foundation, either version 3 of the | |
License, or (at your option) any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU Affero General Public License for more details. | |
You should have received a copy of the GNU Affero General Public License | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#include <stdlib.h> | |
#include "dynarray.h" | |
unsigned int dynarray_init(dynarray_t *array, int initial_capacity) { | |
if (array == NULL || initial_capacity < 1 || (initial_capacity % 2) != 0) { | |
return DYNARRAY_ERROR; | |
} | |
void **data = malloc(sizeof(void *) * initial_capacity); | |
if (data == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
array->data = data; | |
array->initial_capacity = initial_capacity; | |
array->capacity = initial_capacity; | |
array->size = 0; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_size(dynarray_t *array, int *size) { | |
if (array == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
*size = array->size; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_resize(dynarray_t *array, int capacity) { | |
if (array == NULL || array->data == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
void **data = realloc(array->data, sizeof(void *) * capacity); | |
if (data == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
array->data = data; | |
array->capacity = capacity; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_add(dynarray_t *array, void *item) { | |
if (array == NULL || array->data == NULL || item == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
int capacity = array->capacity; | |
int size = array->size; | |
if (size >= capacity) { | |
if (dynarray_resize(array, capacity * 2) != DYNARRAY_SUCCESS) { | |
return DYNARRAY_ERROR; | |
} | |
} | |
array->data[array->size] = item; | |
array->size++; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_set(dynarray_t *array, int index, void *item) { | |
if (array == NULL || array->data == NULL || | |
index < 0 || index >= array->capacity || | |
item == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
array->data[index] = item; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_get(dynarray_t *array, int index, void **item) { | |
if (array == NULL || array->data == NULL || | |
index < 0 || index >= array->size || | |
item == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
*item = array->data[index]; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_remove(dynarray_t *array, int index) { | |
if (array == NULL || array->data == NULL || | |
index < 0 || index >= array->size) { | |
return DYNARRAY_ERROR; | |
} | |
void **data = array->data; | |
int initial_capacity = array->initial_capacity; | |
int capacity = array->capacity; | |
int size = array->size; | |
data[index] = NULL; | |
if (index < (size - 1)) { | |
int current; | |
for (current = index; current < (size - 1); current++) { | |
data[current] = data[current + 1]; | |
data[current + 1] = NULL; | |
} | |
} | |
array->size = --size; | |
int new_capacity = capacity / 2; | |
if (size > 0 && size <= new_capacity && new_capacity >= initial_capacity) { | |
if (dynarray_resize(array, new_capacity) != DYNARRAY_SUCCESS) { | |
return DYNARRAY_ERROR; | |
} | |
} | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_free(dynarray_t *array) { | |
if (array == NULL || array->data == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
free(array->data); | |
array->data = NULL; | |
array->capacity = 0; | |
array->size = 0; | |
return DYNARRAY_SUCCESS; | |
} | |
unsigned int dynarray_deep_free(dynarray_t *array) { | |
if (array == NULL || array->data == NULL) { | |
return DYNARRAY_ERROR; | |
} | |
void **data = array->data; | |
int size = array->size; | |
int index; | |
for (index = 0; index < size; index++) { | |
free(data[index]); | |
} | |
dynarray_free(array); | |
return DYNARRAY_SUCCESS; | |
} |
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
/* | |
dynarray - Simple dynamically sized C arrays. | |
Copyright (C) 2015 Jack Wilsdon | |
This program is free software: you can redistribute it and/or modify | |
it under the terms of the GNU Affero General Public License as | |
published by the Free Software Foundation, either version 3 of the | |
License, or (at your option) any later version. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU Affero General Public License for more details. | |
You should have received a copy of the GNU Affero General Public License | |
along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
/** | |
* @file dynarray.h | |
*/ | |
#ifndef _DYNARRAY_H_ | |
#define _DYNARRAY_H_ | |
/** | |
* @defgroup dynarray Dynamically Sized Arrays | |
* @brief Simple dynamically sized arrays. | |
* @{ | |
*/ | |
/** | |
* @brief Represents a successful result. | |
*/ | |
#define DYNARRAY_SUCCESS 1 | |
/** | |
* @brief Represents an error result. | |
*/ | |
#define DYNARRAY_ERROR (!DYNARRAY_SUCCESS) | |
/** | |
* @brief Represents a dynamically sized array. | |
*/ | |
struct dynarray { | |
/** | |
* @brief The data in the array. | |
*/ | |
void **data; | |
/** | |
* @brief The starting capacity of the array. | |
*/ | |
int initial_capacity; | |
/** | |
* @brief The current capacity of the array. | |
*/ | |
int capacity; | |
/** | |
* @brief The current number of items in the array. | |
*/ | |
int size; | |
}; | |
/** | |
* @brief Represents a dynamically sized array. | |
*/ | |
typedef struct dynarray dynarray_t; | |
/** | |
* @brief Initializes a @ref dynarray "dynamically sized array". | |
* | |
* This method performs the following actions on the provided array | |
* - Allocates an array of pointers for @ref dynarray#data. | |
* - Sets the initial capacity and current capacity to the capacity provided. | |
* - Sets the size to zero. | |
* | |
* This method should not be called on an existing array, instead the array | |
* should be @ref dynarray_free "freed" first. | |
* | |
* @param[in,out] array The array to initialize. | |
* @param[in] initial_capacity The initial capacity of the array. | |
* @return @ref DYNARRAY_SUCCESS if the array was initialized successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_init(dynarray_t *array, int initial_capacity); | |
/** | |
* @brief Retrieves the size of a @ref dynarray "dynamically sized array". | |
* | |
* The size of an array is the current number of item in the array. | |
* | |
* This method uses @ref dynarray#size internally but should be used instead of | |
* @ref dynarray#size as it performs a @c NULL check. | |
* | |
* @param[in] array The array to retrieve the size of. | |
* @param[out] size The size of the array. | |
* @return @ref DYNARRAY_SUCCESS if the size was retrieved successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_size(dynarray_t *array, int *size); | |
/** | |
* @brief Adds an item to a @ref dynarray "dynamically sized array". | |
* | |
* This method appends the provided item to the end of the array. | |
* If the new size of the array is greater than the current | |
* @ref dynarray#capacity "capacity" then the array's capacity is doubled. | |
* | |
* @param[in,out] array The array to add the item to. | |
* @param[in] item The item to add to the array. | |
* @return @ref DYNARRAY_SUCCESS if the item was added successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_add(dynarray_t *array, void *item); | |
/** | |
* @brief Sets the item at an index in a @ref dynarray "dynamically sized array". | |
* | |
* If the index provided is greater than the capacity of the array, | |
* @ref DYNARRAY_ERROR is returned. | |
* | |
* @param[in,out] array The array to place the item in. | |
* @param[in] index The index to place the item at. | |
* @param[in] item The item to place at the index. | |
* @return @ref DYNARRAY_SUCCESS if the item was placed successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_set(dynarray_t *array, int index, void *item); | |
/** | |
* @brief Retrieves an item from a @ref dynarray "dynamically sized array". | |
* | |
* If the index provided is greater than the capacity of the array, | |
* @ref DYNARRAY_ERROR is returned. | |
* | |
* @param[in] array The array to retrieve the item from. | |
* @param[in] index The index of the item to retrieve. | |
* @param[out] item The item at the provided index. | |
* @return @ref DYNARRAY_SUCCESS if the item was retrieved successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_get(dynarray_t *array, int index, void **item); | |
/** | |
* @brief Removes an item from a @ref dynarray "dynamically sized array". | |
* | |
* If the index provided is greater than the capacity of the array, | |
* @ref DYNARRAY_ERROR is returned. | |
* | |
* If the index provided is before the last item of the array it is removed | |
* and all items after it are shifted by one place to the left. | |
* | |
* @param[in,out] array The array to remove the item from. | |
* @param[in] index The index of the item to remove. | |
* @return @ref DYNARRAY_SUCCESS if the item was removed successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_remove(dynarray_t *array, int index); | |
/** | |
* @brief Frees the memory used by a @ref dynarray "dynamically sized array". | |
* | |
* This method performs the following actions on the provided array: | |
* - Frees the memory allocated to @ref dynarray#data (but not it's elements). | |
* - Sets the pointer of @ref dynarray#data to \c NULL. | |
* - Sets the capacity of the array to zero. | |
* - Sets the size of the array to zero. | |
* | |
* @param[in,out] array The array to free. | |
* @return @ref DYNARRAY_SUCCESS if the array was freed successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_free(dynarray_t *array); | |
/** | |
* @brief Frees the memory used by a @ref dynarray "dynamically sized array" and it's elements. | |
* | |
* This method performs the same actions as @ref dynarray_free and also performs following actions on the provided array: | |
* - Frees the memory allocated to each element in the array. | |
* | |
* @param[in,out] array The array to free. | |
* @return @ref DYNARRAY_SUCCESS if the array was freed successfully, | |
* @ref DYNARRAY_ERROR otherwise. | |
*/ | |
unsigned int dynarray_deep_free(dynarray_t *array); | |
/** | |
* @} | |
*/ | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment