C ++这会导致内存泄漏吗?

时间:2015-08-12 18:44:06

标签: c++ memory-leaks

我正在尝试理解delete []的使用。以下代码是否会发生内存泄漏?

int * getArray( )
{
    int *r = new int[10];
    for (int i = 0; i < 10; ++i)
        r[i] = i;
    return r;
}

int main ()
{
    int *array;
    for ( int i = 0; i < 10; i++ ) // main loop
        array = getArray();
    return 0;
}

主循环似乎是为10个数组分配内存,其中只有最后一个数组有一个有效的指针。如果这是内存泄漏,我如何释放存储前9个阵列的内存?

我也可以使用const int r[10];代替int *r = new int[10];进行编译。可以使用const来避免内存泄漏吗?

4 个答案:

答案 0 :(得分:6)

new的每次通话都必须与对delete的通话配对,以避免内存泄漏(或new[]delete[])。

如何删除内存取决于您正在做什么,但由于您不能在for-loop之外保持访问权限,因此您可以轻松地将其删除。 for循环。

for (int i = 0; i < 10; ++i)
{
    array = getArray();
    /* do  something with 'array' */
    delete[] array;
}

更好的是,为什么不使用std::vector<int>并避免直接执行任何内存分配?

修改 正如@Niall在评论中提到的那样,您还应该熟悉std::unique_ptr(假设您的编译器支持它)。它使用RAII(Wikipedia linkcppreference link)来自动处理内存管理。例如,std::unique_ptr<int[]>会在课程超出范围时自动调用delete[]

答案 1 :(得分:3)

  1. 如果您不为每delete(或newnew[])拨打delete[],就会发生内存泄漏。
  2. 你需要跟踪你分配的内存,这个循环:
  3.  for ( int i = 0; i < 10; i++ ) // main loop
        array = getArray();
    
    如你所说,

    将创建无法恢复(前9个阵列)地址的内存。无法获取地址,以便您可以正确处理此内存。你需要做这样的事情:

    int *array[10]
    ...
      for ( int i = 0; i < 10; i++ ) // main loop
        array[i] = getArray();
    

    以便您可以正确删除所有数组:

       for ( int i = 0; i < 10; i++ )
            delete[] array[i];
    

答案 2 :(得分:1)

正如其他答案所解释的那样,您有一个memory leak(使用const对他们没有帮助。)

有几个系统(特别是Linux)将valgrind移植到它们。如果可能的话使用它(在运行时测试)。因此,使用g++ -std=c++11 -Wall -Wextra -g将您的C ++ 11代码编译为./myprog可执行文件,然后运行valgrind ./myprog;它将在运行时为您提供有用的诊断。

使用最近的GCC,您还可以将-fsanitize=address传递给编译器。详细了解address sanitizer

顺便说一句,你应该经常在你的C ++代码中使用smart pointers,例如std::shared_ptrstd::unique_ptr。另请阅读RAIIweak referencesrule of five

您可能还会了解有关garbage collection技术的更多信息(reference counting是一个非常有限的技术,对cyclic图表不友好,但对DAG s来说已经足够了。您可以考虑使用Boehm's conservative garbage collector。另请参阅this

答案 3 :(得分:1)

1 - 你确实有内存泄漏。要解决这个问题,您可以在完成每个阵列后明确删除。

for ( int i = 0; i < 10; i++ ) {
    int *array = getArray();
    // ... Do stuff ...
    delete[];
}

或者为数组返回unique_ptr。这样你就不必删除任何内容。

std::unique_ptr< int[] > getArray( )
{
    std::unique_ptr< int[] > r{ new int[10] };
    for (int i = 0; i < 10; ++i) {
        r[i] = i;
    }
    return std::move( r );
}

在这两种情况下,您都无法猜测数组的大小。你只知道你得到了10个元素的数组。

您可以使用std::array为您管理内存并保持数组长度可见。

2 - 如果您使用static,您将始终返回相同的数组,并且无需删除。