diff --git a/DynamicInt64Array.h b/DynamicInt64Array.h new file mode 100644 index 0000000..010e62c --- /dev/null +++ b/DynamicInt64Array.h @@ -0,0 +1,224 @@ +//myHelper/DynamicInt64Array.h +//Matthew Ellison +// Created: 03-08-19 +//Modified: 03-09-19 +//This is the implementation for a dynamic array in c +/* + Copyright (C) 2019 Matthew Ellison + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + + +#ifndef DYNAMIC_ARRAY_H +#define DYNAMIC_ARRAY_H + + +#include +#include + + +struct DynamicInt64Array{ + int64_t* ptr; //The pointer to the array + uint64_t size; //How many values are stored in the array + uint64_t allocated; //How many values can be stored in the current array +}; + +//This function initializes the array by allocating an array of size 2 and making sure the size trackers have accurate data +void initDynamicInt64Array(struct DynamicInt64Array* ary){ + //If NULL was sent to the function do nothing + if(ary == NULL){ + return; + } + + ary->ptr = (int64_t*)malloc(2*sizeof(int64_t)); + ary->allocated = 2; + ary->size = 0; +} + +//This function frees all of the dynamically allocated memory used in the array. Should be called after array is finished being used +void destroyDynamicInt64Array(struct DynamicInt64Array* ary){ + //If the array passed into the function is NULL do nothing + if(ary == NULL){ + return; + } + + //If memory has been allocated for the array, release it + if(ary->ptr != NULL){ + free(ary->ptr); + } + + ary->ptr = NULL; + ary->size = 0; + ary->allocated = 0; +} + +//This function makes sure there is at least a certain number of elements available in this array +void reserveDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t size){ + //If the array passed into the function is NULL do nothing + if(ary == NULL){ + return; + } + //If you are trying to reserve less than what is already available, do nothing + if(size < ary->allocated){ + return; + } + + //Create a new array with the propper size + int64_t* newAry = (int64_t*)malloc(size * sizeof(int64_t)); + + //Adjust the value of the amount of memory that has been saved for the array + ary->allocated = size; + + //Copy all elements from the old array to the new one + for(uint64_t cnt = 0;cnt < ary->size;++cnt){ + newAry[cnt] = ary->ptr[cnt]; + } + + //Free the space held by the old array + if(ary->ptr != NULL){ + free(ary->ptr); + } + + //Assign the new array to the old array + ary->ptr = newAry; +} + +//This function adds an element to the array, expanding the size if necessary +void pushBackDynamicInt64Array(struct DynamicInt64Array* ary, int64_t num){ + //If NULL was passed into the fuction as a pointer do nothing + if(ary == NULL){ + return; + } + + //If there is not enough room for the new element double the possible size of the array + if(ary->allocated == ary->size){ + reserveDynamicInt64Array(ary, ary->size * 2); //Double the size of the array + } + + //Add the new element to the array + ary->ptr[ary->size] = num; + ++ary->size; +} + +//This function takes the last element off of the array and returns that element +int64_t popBackDynamicInt64Array(struct DynamicInt64Array* ary){ + //If NULL was passed in as a pointer do nothing + if(ary == NULL){ + return 0; + } + + //If there is an element that can be popped off remove it and return it + if(ary->size > 0){ + --ary->size; + return ary->ptr[ary->size]; + } + //Otherwise do nothing + else{ + return 0; + } +} + +//This function removes the first element in the array that matches num +void removeDynamicInt64Array(struct DynamicInt64Array* ary, int64_t num){ + //If NULL was passed to the function as an array do nothing + if(ary == NULL){ + return; + } + + //Look at every element in the array, trying to find one that is the same as num + uint64_t location = 0; + for(location = 0;location < ary->size;++location){ + //If you find an elemenet that is equal to the number break the loop so it will get overwritten + if(ary->ptr[location] == num){ + break; + } + } + + //Everything that is left after finding the correct element gets bumped forward one element + for(++location;location < ary->size;++location){ + ary->ptr[location - 1] = ary->ptr[location]; + } + + //Take size down one to compensate for removing an element + --ary->size; +} + +//This funciton removes the element at loc from the array +void removeLocationDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t loc){ + //If NULL was passed to the function as an array do nothing + if(ary == NULL){ + return; + } + + //Start at the location that you are trying to remove and move every element down one + for(uint64_t location = loc + 1;location < ary->size;++location){ + ary->ptr[location - 1] = ary->ptr[location]; + } + + //Take size down one to compensate for removing an element + --ary->size; +} + +//This function returns the element of the array at loc +int64_t getDynamicInt64Array(struct DynamicInt64Array* ary, uint64_t loc){ + //If NULL was sent to the function as an array do nothing + if(ary == NULL){ + return 0; + } + //Make sure the location is valid before returning the element + if(loc < ary->size){ + return ary->ptr[loc]; + } + else{ + return 0; + } +} + +//This element returns the first location in the array where key is found. returns -1 if key is not found +int64_t findDynamicInt64Array(struct DynamicInt64Array* ary, int64_t key){ + //If NULL was passed to the function as an array return -1 as an error + if(ary == NULL){ + return -1; + } + //Look through the entire array, looking for at element that matches the key + for(uint64_t location = 0;location < ary->size;++location){ + if(ary->ptr[location] == key){ + return location; + } + } + + //If you went all the way through the array without finding a match return -1 as a failure + return -1; +} + +//Returns the size of the dynamic array +uint64_t sizeDynamicInt64Array(struct DynamicInt64Array* ary){ + //If NULL was passed to the function as an array do nothing + if(ary == NULL){ + return 0; + } + return ary->size; +} + +//Returns the number of elements that have been allocated for the current array +uint64_t allocatedDynamicInt64Array(struct DynamicInt64Array* ary){ + //If NULL was passed to the function as an array do nothing + if(ary == NULL){ + return 0; + } + return ary->allocated; +} + +#endif //DYNAMIC_ARRAY_H diff --git a/testDynamicInt64Array.c b/testDynamicInt64Array.c new file mode 100644 index 0000000..82498c5 --- /dev/null +++ b/testDynamicInt64Array.c @@ -0,0 +1,146 @@ +//myHelper/DynamicInt64Array.h +//Matthew Ellison +// Created: 03-08-19 +//Modified: 03-09-19 +//This is the test for my dynamic array in c +/* + Copyright (C) 2019 Matthew Ellison + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + + +#include +#include "DynamicInt64Array.h" + + +int main(){ + printf("BEGIN TESTS\n\n\n"); + + //Define a dynamic array + struct DynamicInt64Array testAry; + + //Initialize the array + initDynamicInt64Array(&testAry); + + //Set some elements in the array + pushBackDynamicInt64Array(&testAry, 0); + pushBackDynamicInt64Array(&testAry, 1); + pushBackDynamicInt64Array(&testAry, 2); + pushBackDynamicInt64Array(&testAry, 3); + pushBackDynamicInt64Array(&testAry, 4); + pushBackDynamicInt64Array(&testAry, 5); + + if((testAry.ptr[0] == 0) && (testAry.ptr[1] == 1) && (testAry.ptr[2] == 2) && (testAry.ptr[3] == 3) && (testAry.ptr[4] == 4) && (testAry.ptr[5] == 5)){ + printf("Adding numbers to the array worked correctly\n"); + } + else{ + printf("Something went wrong adding numbers to the array\n"); + printf("The numbers are: %d %d %d %d %d %d\n", testAry.ptr[0], testAry.ptr[1], testAry.ptr[2], testAry.ptr[3], testAry.ptr[4], testAry.ptr[5]); + return 1; + } + + //Check that the size is correct + if(testAry.size != 6){ + printf("Something is wrong with the size: %d\nIt should be &d\n", testAry.size, 6); + return 1; + } + if(testAry.allocated != 8){ + printf("Something is wrong with the allocated size: %d\nIt should be %d\n", testAry.allocated, 8); + return 1; + } + + //Get some elements from the array + if((getDynamicInt64Array(&testAry, 0) == 0) && (getDynamicInt64Array(&testAry, 4) == 4) && (getDynamicInt64Array(&testAry, 6) == 0)){ + printf("The get function is working correctly\n"); + } + else{ + printf("The get function has a problem. The numbers are:\n%d %d %d\nThe numbers should be:\n%d %d %d", getDynamicInt64Array(&testAry, 0), getDynamicInt64Array(&testAry, 4), getDynamicInt64Array(&testAry, 6), 0, 4, 0); + return 1; + } + + //Search the array for an element + if((findDynamicInt64Array(&testAry, 5) == 5) && (findDynamicInt64Array(&testAry, 3) == 3) && (findDynamicInt64Array(&testAry, 7) == -1)){ + printf("The find function is working correctly\n"); + } + else{ + printf("The find function has a problem\nThe numbers are: %d %d %d\nThey should be: %d %d %d\n", findDynamicInt64Array(&testAry, 5), findDynamicInt64Array(&testAry, 3), findDynamicInt64Array(&testAry, 7), 5, 3, -1); + return 1; + } + + //Add an element to the array + pushBackDynamicInt64Array(&testAry, 6); + if(testAry.ptr[6] == 6){ + printf("The pushback function is working correctly\n"); + } + else{ + printf("There is a problem in the pushback function\n"); + return 1; + } + if(testAry.size != 7){ + printf("There is a problem with the size after adding to the array\n"); + printf("The size is %d and it should be %d\n", testAry.size, 7); + return 1; + } + + //Remove an element from the array + removeDynamicInt64Array(&testAry, 2); + if((testAry.ptr[2] == 3) && (testAry.ptr[3] == 4) && (testAry.ptr[4] == 5) && (testAry.ptr[5] == 6)){ + printf("Removing funcion is working correctly\n"); + } + else{ + printf("There is a problem with the remove function\n"); + return 1; + } + if(testAry.size != 6){ + printf("There is a problem with the size after using the remove function\n"); + return 1; + } + + removeLocationDynamicInt64Array(&testAry, 4); + if(testAry.ptr[4] == 6){ + printf("RemoveLocation function is working correctly\n"); + } + else{ + printf("There is a problem with the removeLocation function\n"); + printf("The number is %d it should be %d\n", testAry.ptr[4], 6); + return 1; + } + if(testAry.size != 5){ + printf("There is a problem with the size after using the removeLocation function\n"); + return 1; + } + + //Release all of the memory allocated by the array + destroyDynamicInt64Array(&testAry); + + printf("\n\nEND OF TESTS\n"); + + return 0; +} + +/* Results: +BEGIN TESTS + + +Adding numbers to the array worked correctly +The get function is working correctly +The find function is working correctly +The pushback function is working correctly +Removing funcion is working correctly +RemoveLocation function is working correctly + + +END OF TESTS +*/