是否在同一指针上调用new []两次而不调用之间的delete []导致内存泄漏?

时间:2012-04-02 16:05:32

标签: c++ memory-leaks

我听说你每次使用“new”时都应该“删除”,但是当我运行一个简单的测试程序(如下)时,我为arraySize或numLoops添加的数字似乎没什么区别。这会导致内存泄漏吗?

#include <iostream>

int main()
{
    double *array;
    const int arraySize = 100000;
    const int numLoops = 100000;

    for (int i = 0; i < numLoops; i++)
    {
        // do I need to call "delete [] array;" here?
        array = new double[arraySize];
    }

    int x;
    std::cin >> x; // pause the program to view memory consumption

    delete [] array;

    return 0;
}

6 个答案:

答案 0 :(得分:9)

不,这还不够。

每次调用newnew[]时,都会分配一些内存,并为您提供该内存的地址(以便能够使用它)。每段内存最终必须为delete d(或delete[] d)。

您将该地址存储在array中,但在下一次迭代时立即覆盖该地址。因此,您无法delete - 已经分配了所有内存。因此,您有内存泄漏。

答案 1 :(得分:4)

有助于正确理解您实际上在做什么。

您没有在同一指针上调用new[]两次。您正在调用new[]两次,并将两个结果存储到同一指针中。 new[]只返回指向已分配内存的指针。为避免泄漏内存,您必须在某个时刻再次释放内存。但是指针不是内存,它只是一个指针,告诉你分配的内存的位置。

因此,您始终可以覆盖指针,将其设置为指向新的不同地址。然后你就失去了使用所指向的所有知识。如果它曾经指向你应该释放的内存,那么你就不能再找到那块内存了,所以你再也不能在它上面调用delete[]了,所以......它被泄露了。

答案 2 :(得分:2)

是。你没有在指针上调用new,你调用new并返回指向已分配内存的指针。您有责任保留该指针并将其删除。如果你像现在一样覆盖那个值,那么你就是在泄漏。

答案 3 :(得分:1)

每当您new(或new[])内存必须 delete(或delete[])时,它或它都会泄漏。

每次调用new时,如果new操作成功,则返回指向堆分配对象的指针。如果指向此内存的指针超出范围或被重新分配(即您在此处执行的操作),那么您将无法以后删除内存。

在您的代码示例中,仅销毁最后分配的内存。您可以使用process explorer甚至任务管理器之类的东西来检查内存泄漏。

答案 4 :(得分:1)

是。幸运的是,有一种更好的方法 - 使用std::vector

而不是直接分配内存
#include <iostream>
#include <vector>

int main()
{
    double *array;
    const int arraySize = 100000;
    const int numLoops = 100000;

    for (int i = 0; i < numLoops; i++)
    {
       std::vector<double> array(arraySize);
       // use it just like a normal array
    }

    int x;
    std::cin >> x; // pause the program to view memory consumption
    return 0;
}

循环的每次迭代都会销毁vector(以及它控制释放的内存)。

除非您确实需要,否则通常不应使用new。我甚至可以说从来没有需要(甚至是很好的理由)使用new的数组形式。

答案 5 :(得分:1)

两个问题,两个答案。

问题一:在同一指针上调用new []两次而不调用之间的delete []会导致内存泄漏吗?

答案一:并非总是如此,但99%的时间是肯定的。下面的代码使用指向数组的指针调用new两次,但第一次将分配的内存的地址分配给array2,第二次将地址保存到自身。在这种情况下,可以删除这两个数组。

#include <iostream>

int main()
{
    double *array;
    double *array2;
    const int arraySize = 100000;

    for (int i = 0; i < 2; i++)
    {
        // do I need to call "delete [] array;" here?
        array = new double[arraySize];
        if(i == 0)
        {
            array2 = array;
        }
    }

    int x;
    std::cin >> x; // pause the program to view memory consumption

    delete [] array;
    delete [] array2;

    return 0;
}

问题二:delete []的这种用法是否足够?

答案二:不,因为删除调用只影响你给它的指针指向的地址。当您在示例中覆盖指针时,它会删除最后分配的内存部分