0
votes

I have a recursive function that requires me to create a new array every time the function is called. The function also requires the array that was previously created:

void myFunc(int* prevArray)
{
int newSize;
//do some calculations to find newSize
int* newArray;
newArray = new int[newSize];
//do some calculations to fill newArray
//check some stopping condition
myFunc(newArray);
}

This function leaks memory, but I can't avoid that by adding

delete[] newArray;

since I can only add that after calling the function again. How can I solve this?

3
What's the problem with doing delete[] newArray; after the call to myFunc? - Joseph Mansfield
Well, it would keep stacking up memory for as long as the recursion keeps going. The arrays are quite large, and I need to call this function a lot. - RobVerheyen
You can delete prevArray unless it equals nullptr. - CouchDeveloper
@RobVerheyen Well that seems to be a natural consequence of your algorithm - each successive call to myFunc requires a large array computed by the previous call. - Joseph Mansfield
Doesn't prevArray get copied from the previous instance? - RobVerheyen

3 Answers

1
votes

You can solve this by making use of dynamic memory allocation.

// allocate initial size
const int INITIAL_SIZE = 5;
int *myArray = malloc(sizeof(int) * INITIAL_SIZE));

int myFunc(int *aArray, int numAllocated) {
    int numElements = calculateNewSize();

    if (numElements != numAllocated) {
        // allocate new size
        realloc(aArray, (numElements * sizeof(int));
    }

    return numElements;
}

Now you can call myFunc like this:

int numElements;

numElements = myFunc(myArray, numElements);

When your done using myFunc don't forget to free the memory

free(myArray);
1
votes

Try something like

void myFunc(int* prevArray)
{
    int newSize;
    ...newArray = new int[newSize];
    myFunc(newArray);
    delete[] newArray;
}

or better yet use std::unique_ptr to control the newArray memory. In this way you will follow the rule of thumb regarding dynamic memory - that it should have one owner, responsible for both allocating and freeing it.

1
votes

You might just use a vector and swap the new result into the final result.

#include <iostream>
#include <vector>

struct X { ~X() { std::cout << "Destruction\n"; } };
void recursive(unsigned n, std::vector<X>& result) {
    // Put new_result in a scope for destruction
    {
        std::vector<X> new_result(1);

        // Do something

        // The previous result is no longer needed
        std::swap(result, new_result);
    }

    // Next recursion
    if(n) {
        std::cout << "Call\n";
        recursive(--n, result);
    }
}

int main() {
    std::vector<X> result(1);
    std::cout << "Call\n";
    recursive(3, result);
    return 0;
}