I'm trying to dynamically increase the capacity of an array but I keep getting memory leaks when running with valgrind. This is the code I'm running(nothing wrong with it shouldn't be the problem):
//My struct
struct ArrayList{
int size; //amount of items in a array
int capacity; //the capacity of an array
int* items; //the array itself
};
//Dynamically create an array
ArrayList* createList(int m){
ArrayList* n = new ArrayList;
n->size = 0;
n->capacity = m;
n->items = new int[n->capacity];
return n ;
}
//Destroy an array
void destroyList(ArrayList* List){
delete[] List->items;
delete List;
}
The code to double the capacity(Where I get the memory leak):
// double the capacity of an array by dynamically creating a new one and transfering the old values to it
void doubleCapacity(ArrayList* List){
// save everything
int saved_size = List->size;
int saved_capacity = List->capacity;
int* saved_items = new int[List->size];
for (int i = 0 ; i < List->size;i ){
saved_items[i] = List->items[i];
}
// load everything
destroyList(List);
List->size = saved_size;
List->capacity = saved_capacity*2;
List->items = new int[List->capacity];
for (int i = 0; i < List->size; i ){
List->items[i] = saved_items[i];
}
delete[] saved_items;
}
My main that tests the code for doublecapacity.
int main() {
// Run tests
ArrayList* l = createList(4);
l->size ;
l->items[0] = 1;
cout << l->size << endl;
cout << l->capacity << endl;
cout << l->items[0] << endl;
doubleCapacity(l);
cout << l->size << endl;
cout << l->capacity << endl;
cout << l->items[0] << endl;
destroyList(l);
return 0;
}
CodePudding user response:
Your doubleCapacity()
function is implemented all wrong.
It is creating a temporary array of the original size
just to save a redundant copy of the current items
. Then it creates a new array of the desired capacity
and copies the temporary items into it. You don't need that temporary array at all, you can copy the original items directly into the final array.
More importantly, you are destroying the ArrayList
object itself, so any access to its members after it has been destroyed is undefined behavior.
Try something more like this instead:
void doubleCapacity(ArrayList* List){
if (List->capacity > (std::numeric_limits<int>::max() / 2))
throw std::overflow_error("capacity is too high to double");
int new_capacity = List->capacity * 2;
int* new_items = new int[new_capacity];
for (int i = 0; i < List->size; i ){
new_items[i] = List->items[i];
}
delete[] List->Items;
List->items = new_items;
List->capacity = new_capacity;
}