In the function *expandArrayList and *trimArrayList I need to allocate either more memory or less memory to the given array. Right now I am using malloc on a new array and then transferring the elements of the original array to the new array, freeing the original array, and then reassigning it to the new array so it's size and capacity are either bigger or smaller than the original. I feel like there has to be a simpler way to do this with either realloc or calloc, but I cant find sufficient information on either online. Would I be able to use either to make this easier and the code cleaner?
Also, these are character arrays that contain several character arrays inside them, so I was wondering what the best way to transfer the contents of one array to the other would be. I have gone between
Code:
//example
for (i=0; i<length; i++){
newarray[i] = oldarray[i];
}
and
Code:
for (i=0; i<length; i++){
strcpy(newarray[i], oldarray[i]);
}
but I'm not sure which one (if either) should work.
The 'ArrayList.h' file that is included contains the structure ArrayList, as well as the function prototypes for the functions listed below.
Here is the structure in ArrayList.h:
Code:
#define DEFAULT_INIT_LEN 10
typedef struct ArrayList
{
// We will store an array of strings (i.e., an array of char arrays)
char **array;
// Size of list (i.e., number of elements that have been added to the array)
int size;
// Length of the array (i.e., the array's current maximum capacity)
int capacity;
} ArrayList;
Here is my code:
Code:
//included libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ArrayList.h"
//Create arraylist
ArrayList *createArrayList(int length){
//Dynamically allocate space for new ArrayList
ArrayList *L = malloc(sizeof(ArrayList));
int i;
//initialize to NULL
L->array = NULL;
//set the size of the arraylist to whichever one is bigger
if (length >= DEFAULT_INIT_LEN)
{
//create arraylist of size length
L->array = malloc(sizeof(char*)*length);
if (L->array != NULL)
{
printf("-> Created new ArrayList of size %d\n",length);
//initialize pointers in array to NULL
for (i=0; i<length; i++){
L->array[i] = NULL;
}
//Set size and capacity
L->size = 0;
L->capacity = length;
return L;
}
//In case malloc fails
else{
printf("\n malloc failed.\n");
return NULL;}
}
//if length is smaller than default size
else
{
//set arraylist to size DEFAULT_INIT_LEN
L->array = malloc(sizeof(char*)*DEFAULT_INIT_LEN);
if (L->array != NULL)
{
printf("-> Created new ArrayList of size %d\n",DEFAULT_INIT_LEN);
//initialize pointers in array to NULL
for (i=0; i<DEFAULT_INIT_LEN; i++){
L->array[i] = NULL;
}
//set size and capacity
L->size = 0;
L->capacity = DEFAULT_INIT_LEN;
return L;
}
//in case malloc failed
else{
printf("\nmalloc failed.\n");
return NULL;
}}}
//Destroy arraylist
ArrayList *destroyArrayList(ArrayList *list){
int i;
//free everything in the array first, then free the array itself
for (i=0; i<list->capacity; i++){
free(list->array[i]);
}
free(list->array);
list->size = 0;
list->capacity = 0;
free(list);
//set list to NULL and return list
list = NULL;
return list;
}
//Expand arraylist to new size
ArrayList *expandArrayList(ArrayList *list, int length){
int i;
char **newarray = NULL;
//find how many elements are currently in the array
int arrsize = sizeof(list->array)/sizeof(list->array[0]);
//create a new (larger) array to store the contents of the old array
newarray = malloc(sizeof(char*)*length);
//dont do anything if the length is smaller than the current capcity
//or if the list was NULL
if (length <= list->capacity)
return NULL;
if (list == NULL)
return NULL;
//make sure malloc was successful
if (newarray != NULL){
//copy the contents of list->array into newarray
for (i=0; i<length; i++){
strcpy(newarray[i], list->array[i]);}
//free the orginal array, since it has been copied over to the new array
for(i=0; i<list->capacity; i++){
free(list->array[i]);
}
free(list->array);
//set list->array to point to the newly created array
list->array = &newarray;
//let user know the function was successful
printf("-> Expanded ArrayList to size %d", length);
//set new size and capacity if they were changed
list->size = arrsize;
list->capacity = length;
//return the pointer to
return list;
}
//if malloc was unsuccessful
else
{
printf("\nmalloc failed\n");
return NULL;
}
}
//trim the arraylist if it's capacity is larger than its current size
ArrayList *trimArrayList(ArrayList *list){
int i;
char **newarray = NULL;
//trim length only if list->capacity is greater than list->size
if (list->capacity <= list->size )
return list;
//create new (smaller) array to hold elements of the original arraylist
newarray = malloc(sizeof(char*)*list->size);
if (newarray != NULL){
//transfer elements of old array into new array
for (i=0; i<list->size; i++){
strcpy(newarray[i], list->array[i]);
}
//inform user of change
printf("-> Trimmed ArrayList to size %d", list->size);
//free memory associated with old array
for (i=0; i<list->size; i++){
free(list->array[i]);
}
//set the old array equal to the newer trimmed array
list->array = newarray;
//update capacity
list->capacity = list->size;
return list;
}
else{
printf("\nmalloc failed\n");
return NULL;
}}
Any help will be greatly appreciated.