关于C ++:如何删除函数返回的数组

How to delete an array that a function returns

我是C ++的新手,并且有一个小的内存泄漏问题。 程序的结构非常简单,如下所示,尽管我省略了与该问题无关的部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int** foo(int sizeOfArray){

     int** arrayToReturn = new int*[sizeOfArray];

     for (int i = 0; i < sizeOfArray; i++) {
           arrayToReturn[i] = new int[2];
     }
     return arrayToReturn;
}

int main() {      
    a = someNumber;                // 'a' can be any value ( < 64)
    int** someArray = foo(int a);
    // Do stuff with someArray
}

因此,从本质上讲,它调用一个返回数组数组的函数。 我的问题是,当我的程序数千次调用此函数时,它们会导致内存泄漏,因为自从我使用NEW以来,我需要使用delete。 我只是不确定如何删除数组,因为我需要在主函数中使用它们,因此无法在函数foo中删除它们,但是之后如何删除它们呢? 我尝试仅删除someArray,但是从行arrayToReturn[i] = new int[2]用尽的内存永远不会释放。

希望这是有道理的,如果这是一个愚蠢的问题,我们深表歉意,并感谢您的阅读!


要完全删除该数组,包括其中的子数组,可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
// Assuming we have an array called 'array'
int** array = foo(bar);

// Iterate through all the sub-arrays and delete them
for (int i = 0; i < sizeOfArray; i++) {    
   delete [] array[i];
}

// Delete the primary array
delete [] array;

该代码存在一些样式问题,有些人可能试图告诉您不要使用原始指针,但是我只是想为您简单地回答这个问题。

与创建数组所用的操作基本上相反。首先创建外部数组,然后遍历并创建子数组,要删除,首先需要删除子数组,然后删除最外面的数组。


这不是很棒的C ++,我不记得上一次在数组上使用过new和delete了。但是理所当然的是,您在学习时需要知道它的工作原理,因此请继续努力并祝您好运!

以下是int s数组的相关代码:

1
2
3
int* foo = new int[20];
// free the array
delete [] foo;


参见" deleteArray"功能。您几乎必须先删除子数组。然后,您删除顶级数组。学习记忆管理是一项很好的技能。一旦学习了内存管理(使用" new"和" delete"),就应该了解STL容器。实际上,人们将使用STL。

我还添加了打印功能,因此您可以看到它的外观。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>

int** foo(int sizeOfArray){
    int** arrayToReturn = new int*[sizeOfArray];

    for (int i = 0; i < sizeOfArray; i++) {
        arrayToReturn[i] = new int[2];
        for (int j = 0; j < 2; j++){
            arrayToReturn[i][j] = j;
        }
    }

    return arrayToReturn;
}

void printArray(int **array, int sizeOfArray){
    for(int i = 0; i < sizeOfArray; i++){
        for(int j = 0; j < 2; j++){
            std::cout << array[i][j] <<"";

        }
        std::cout <<  std::endl;
    }
}

void deleteArray(int **array, int sizeOfArray){
    // Do the inverse of foo
    // Delete the sub arrays (ones with size 2)
    for(int i = 0; i < sizeOfArray; i++){
        delete [] array[i];
    }

    // Then delete the entire array
    delete [] array;
}      

int main(){
    int a = 34;
    int **someArray = foo(a);
    printArray(someArray, a);

    std::cout << someArray << std::endl;

    // Delete pieces of memory
    deleteArray(someArray, a);

    // Readability as well. Set our local reference to NULL
    // Also, will make sure we can't use someArray elsewhere
    someArray = NULL;


    // This 'printArray' call would cause a segfault
    // printArray(someArray, a);

    return 0;
}

对于初学者,您必须按照与分配相反的顺序删除指针。

您可以编写一个可以通过以下方式完成任务的函数

1
2
3
4
5
6
7
8
9
void free( int **array, int sizeOfArray )
{
    for ( int i = 0; i < sizeOfArray; i++ )
    {
        delete [] array[i];
    }

    delete [] array;
}

或者甚至可以像

1
2
3
4
5
6
7
8
9
10
11
void free( int ** &array, int sizeOfArray )
{
    for ( int i = 0; i < sizeOfArray; i++ )
    {
        delete [] array[i];
    }

    delete [] array;

    array = nullptr;
}

除了自己分配和释放内存,您可以使用在标题中声明的标准类std::vector

例如,您的数组可以定义为

1
std::vector<std::vector<int>> array( sizeOfArray, std::vector<int>( 2 ) );

在这种情况下,您不必担心释放内存。


解决此问题的标准方法是首先不要走这条路。

std::vector是满足您所有动态数组需求的一站式服务,而std::array代表静态数组。总而言之,我们得到了一个漂亮的二维数组,该数组恰好在内存中是连续的,并且一旦超出范围就会立即释放。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <vector>
#include

std::vector<std::array<int, 2>> foo(int sizeOfArray){

    return std::vector<std::array<int, 2>>(sizeOfArray);
}

int main() {
    int a = 50; // your number here
    std::vector<std::array<int, 2>> someArray = foo(a);
    // Do stuff with someArray


} //someArray goes out of scope and is destoyed, freeing all of the allocated memory