递归传递动态变量的内存泄漏

Posted

技术标签:

【中文标题】递归传递动态变量的内存泄漏【英文标题】:Memory leaks passing dynamic variables recursively 【发布时间】:2014-01-28 09:15:54 【问题描述】:

我有一个递归函数,每次调用该函数时都需要创建一个新数组。该函数还需要之前创建的数组:

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

这个函数会泄漏内存,但我无法通过添加来避免这种情况

删除[] newArray;

因为我只能在再次调用该函数后添加它。我该如何解决这个问题?

【问题讨论】:

在调用myFunc之后做delete[] newArray;有什么问题? 好吧,只要递归继续进行,它就会一直堆积内存。数组相当大,我需要经常调用这个函数。 你可以删除prevArray,除非它等于nullptr。 @RobVerheyen 好吧,这似乎是您算法的自然结果 - 每次连续调用 myFunc 都需要一个由前一次调用计算的大数组。 不会从前一个实例中复制 prevArray 吗? 【参考方案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);

【讨论】:

这似乎是一个很好的解决方案,但问题是 newArray 的内容取决于 prevArray 的内容。我知道 realloc 保留了旧内存块中的所有内容,但我的 newArray 不仅仅是我的旧数组,最后添加了一些东西。它们表示在它们之间完成了一些线性代数的矩阵。 我没看出问题,那你为什么不初始化数组呢?元素的数量是给定的变量,因此很容易编写一个初始化函数来迭代所有元素。【参考方案2】:

试试类似的东西

void myFunc(int* prevArray)

    int newSize;
    ...newArray = new int[newSize];
    myFunc(newArray);
    delete[] newArray;

或者更好的是使用 std::unique_ptr 来控制 newArray 内存。通过这种方式,您将遵循有关动态内存的经验法则 - 它应该有一个所有者,负责分配和释放它。

【讨论】:

【参考方案3】:

您可能只是使用向量并将新结果交换为最终结果。

#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;

【讨论】:

我不完全确定我是否理解您的意思。结构是否意味着包含我的数组? 不,它的目的只是为了显示删除点 - std::vector 将是您的选择

以上是关于递归传递动态变量的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

分析 ThreadLocal 内存泄漏问题

深入分析 ThreadLocal 内存泄漏问题

java多线程--------深入分析 ThreadLocal 内存泄漏问题

转载深入分析 ThreadLocal 内存泄漏问题

Android内存泄漏查找和解决

闭包为什么会造成内存泄漏?