Утечки памяти, передавая динамические переменные рекурсивно

0

У меня есть рекурсивная функция, которая требует, чтобы я создавал новый массив каждый раз, когда вызывается функция. Для функции также требуется массив, который был ранее создан:

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);
}

Эта функция утечки памяти, но я не могу этого избежать, добавляя

delete [] newArray;

так как я могу только добавить, что после вызова функции снова. Как я могу это решить?

  • 5
    В чем проблема с delete[] newArray; после звонка на myFunc ?
  • 0
    Что ж, это сохранит память до тех пор, пока продолжается рекурсия. Массивы довольно большие, и мне нужно часто вызывать эту функцию.
Показать ещё 7 комментариев
Теги:
recursion
memory-leaks

3 ответа

1
Лучший ответ

Вы можете решить эту проблему, используя динамическое распределение памяти.

// 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;
}

Теперь вы можете вызвать myFunc следующим образом:

int numElements;

numElements = myFunc(myArray, numElements);

Когда вы закончили с помощью myFunc, не забудьте освободить память

free(myArray);
  • 0
    Это кажется хорошим решением, но проблема заключается в том, что содержимое newArray зависит от содержимого prevArray. Я знаю, что realloc сохраняет все, что было в старом блоке памяти, но мой newArray - это не просто мой старый массив с добавленными в конец вещами. Они представляют собой матрицы, между которыми имеется некоторая линейная алгебра.
  • 0
    Я не вижу проблемы, почему бы вам не инициализировать массив тогда? Число элементов является заданной переменной, поэтому легко написать функцию инициализации для итерации по всем элементам.
1

Попробуйте что-нибудь вроде

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

или еще лучше использовать std :: unique_ptr для управления памятью newArray. Таким образом, вы будете придерживаться эмпирического правила относительно динамической памяти - что у него должен быть один владелец, ответственный за распределение и освобождение.

1

Вы можете просто использовать вектор и поменять новый результат на конечный результат.

#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;
}
  • 0
    Я не совсем уверен, понимаю ли я, что вы имеете в виду. Структура должна содержать мой массив?
  • 0
    Нет, это просто показать точку удаления - std :: vector <int> будет вашим выбором

Ещё вопросы

Сообщество Overcoder
Наверх
Меню