查找数组之间的内存泄漏

时间:2016-09-25 13:40:25

标签: c++ memory-leaks

我认为这对你们来说相当简单..在我的程序中某处我有内存泄漏..但我似乎无法找到它......我很确定它与数组有关。

我的程序用于获取1个整数参数,创建该大小的数组,然后创建另一个整数的双数组(全部填充随机值)。

所以举个例子 输入= 4 输出= 54 73 18 92
52 20 67 6 14 38 87 19 77

我想我没有正确删除数组......

继承我目前的代码:

#include <iostream>
#include <cstdlib>
using namespace std;

int* initArray(int);
int fillArray(int *, int);
int* doubleArray(int *, int);
void displayArray(int *, int);

/* 
 * The program will create an array of given size
 * populate the array with random number from (0-99)
 * and display the array. Next, the program will double
 * the size of the array, repopulate the array and 
 * display it again.
 */


int main(int argc, char ** argv){
    if (argc != 2){
        cout << "wrong number of arguments" << endl;
        exit(1);
    }

    int n = atoi(argv[1]); // get size
    srand(time(0));

    // create initial array and display it
    int* ptr = initArray(n);
    fillArray(ptr, n);
    displayArray(ptr, n);

    // create the double sized array and display it
    doubleArray(ptr, n);
    fillArray(ptr, 2*n);
    displayArray(ptr, 2*n);
}

// Create an array of size n and return its address
int* initArray(int n){
    int arr[n];
    int *ptr = arr;
    return ptr;
}

// Fill array ptr with n random numbers
int fillArray(int *ptr, int n){
    for(int i=0; i<n; i++){
        ptr[i] = rand() % 100;
    }
}

// Double the size of the array, make sure no memory leak
int* doubleArray(int *ptr, int n){
    int size = 2*n;
    int * tmp = new int[size];
    ptr = tmp;
    delete tmp;
    return ptr;
}

// Display n array elements
void displayArray(int *ptr, int n){
    for(int i=0; i<n; i++){
        cout << ptr[i] << " ";
    }
    cout << endl;
}

当我现在运行它,输入为4时,我的输出如下所示: 34 6 4199259 1 90 6 4199259 1 88 32 94 77

某些值相同的事实告诉我,我没有正确清除内存,我认为它与删除第一个数组我清除然后删除第二个数据有关...但我可以真的很清楚

任何帮助都会非常棒

3 个答案:

答案 0 :(得分:5)

int* initArray(int n){
int arr[n];
int *ptr = arr;
return ptr;
 }

在上面的代码中,您将返回一个指向局部变量arr的指针。当此函数的范围结束时,使用ptr是未定义的行为。

int* doubleArray(int *ptr, int n){
int size = 2*n;
int * tmp = new int[size];
ptr = tmp;
delete tmp;
return ptr;
}

在这里删除tmp指向的内存。现在使用指向已删除内存的ptr即使在同一个函数内也是未定义的行为。

解决方案:在函数内动态分配内存

 int *arr =new int[number_of_elements_required];
 return arr;

答案 1 :(得分:3)

让我们仔细看看你的initArray函数:

int* initArray(int n){
    int arr[n];
    int *ptr = arr;
    return ptr;
}

在此声明 本地 变量arr。然后返回指向该数组的指针。当函数返回时,数组将超出范围,留下一个迷路指针,导致未定义的行为

您需要在main函数中创建数组,或者在initFunction中动态创建数组。

尽管IMO最好的解决方案是根本不使用数组或动态内存分配,而是使用std::vector

答案 2 :(得分:0)

<强> Undefined Behaviors

int fillArray(int *ptr, int n){
    for(int i=0; i<n; i++){
        ptr[i] = rand() % 100;
    }
}

此函数返回一个int,但您没有返回。这会导致未定义的行为,在这种情况下可能会损坏您的堆栈,导致程序中的其他位置发生段错误或奇怪的行为。

int* doubleArray(int *ptr, int n){
    int size = 2*n;
    int * tmp = new int[size];
    ptr = tmp;
    delete tmp;
    return ptr;
}

您正在使用tmp分配new[],但是您正在使用delete而不是delete[]销毁它。这也是UB,是导致内存泄漏的潜在原因。

请注意,内存泄漏本身不是UB。

由于我的编译器,我确实注意到了这两个问题。始终启用警告(在-Wall -Wextra / gcc上使用clang)并仔细阅读 - 他们可以为您发现一些问题。

int* initArray(int n){
    int arr[n];
    int *ptr = arr;
    return ptr;
}

正如Joachim Pileborg和Gaurav Sehgal所说,你也会触发UB,因为你正在返回指向本地并使用它的指针,而它应该被摧毁在范围之外。

你真的得到了内存泄漏吗?

  

某些值相同的事实告诉我,我没有正确清除内存,我认为它与删除第一个数组我清除然后删除第二个数据有关...但我可以& #39; t很清楚

这可能不是由内存泄漏引起的。内存泄漏只会泄漏内存,并耗尽程序的可用内存。这不可能发生 - 内存仍然被分配(这正是泄漏),这意味着它不会再被分配用于其他用途。您的问题看起来真的是由堆栈损坏引起的,堆栈损坏有很多机会由我和其他人指出的UB引起。

其他替代方案

听起来std::vector可能符合您的需求 - 您在使用STL容器时获得了所有优势 - 迭代器,通用算法等 - 尤其是动态内存分配的抽象,这将有助于您避免遇到的一些问题。

如果你至少可以使用C ++ 11,你也可以在smart pointers中找到用途。