Home > front end >  Can't get rid of memory leak in c
Can't get rid of memory leak in c

Time:11-27

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;
}
  • Related