2016-11-09 4 views
1

私はC++を初めて使用しています。メモリリークの問題があります。私のプログラムの構造は、以下に示すように非常に単純ですが、問題に無関係な部分は除外しています。関数が返す配列を削除する方法

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]行から使用されたメモリは決して解放されません。

うまくいけば、それは愚かな質問であり、読んでいただければ幸いです。

+4

生ポインタを使用しないで、 'std :: unique_ptr'のようなC++ポインタクラスを使用してください。さらに、それがあなたが実際に撮影しているものであれば、std :: vector >を使うのではなく、自分自身で行うよりもはるかに良いでしょう – pat

+0

vectorまたはunique_ptrのどちらも使用したことはありません。一度スコープ外に割り当てを解除しますか?彼らは使い方を学ぶのは簡単ですか?そして、私は生のポインタで欲しいものを達成する方法がないのですか? –

+2

@MatthewFennellどちらも手作業によるメモリ管理を学ぶより簡単です。 – user2079303

答えて

0

まず、ポインタをその割り当てと逆の順序で削除する必要があります。

あなたは標準クラスを使用することができます代わりに自分自身を割り当て、メモリを解放するタスクに次のよう

void free(int **array, int sizeOfArray) 
{ 
    for (int i = 0; i < sizeOfArray; i++) 
    { 
     delete [] array[i]; 
    } 

    delete [] array; 
} 

それともそれも

void free(int ** &array, int sizeOfArray) 
{ 
    for (int i = 0; i < sizeOfArray; i++) 
    { 
     delete [] array[i]; 
    } 

    delete [] array; 

    array = nullptr; 
} 

のように定義することができますを行います関数を記述することができますstd::vectorがヘッダに宣言されている<vector>

たとえば、配列は

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

この場合、メモリの解放について気にする必要はありません。

1

これは素晴らしいことではありません。C++では、私が最後に使用したアレイを覚えていません。それはずっと前です。しかし、あなたが学んでいるときにどのように動作するのかを知る必要がありますので、それと幸運を押してください!

ここintの配列に関連するコードです:

int* foo = new int[20]; 
// free the array 
delete [] foo; 
+0

これは私の問題を解決しません。私はそれが作成されたスコープにいなくなったときに配列を削除する方法が必要です。 –

+0

OPの質問はギザギザの配列であることに注意してください。この答えは少し単純です。 – user4581301

+0

ええ、設計通りです。私にとっては宿題のようです。配列の先頭へのポインタがあれば、delete [] ptrで配列全体を削除することができます。これを知っていれば、それを配列の配列などに適用することができます。 – Hal

2

完全に内のサブ配列を含むアレイを削除するには、次の操作を行うことができます:

あり
// 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; 

このコードにはいくつかのスタイルの問題があり、生ポインタを決して使用しないように指示する人もいるかもしれませんが、私は単純な方法で質問に答えたいと思っています。

基本的には、アレイの作成に使用した操作の逆の順序です。最初に外側の配列を作成し、次にサブ配列を繰り返して作成しました。削除のために、最初にサブ配列を削除してから、最も外側の配列を削除する必要があります。

0

この問題の標準的な解決策は、最初にこのパスをとらないことです。

std::vector is the one stop shop for all your dynamic array needsおよびstd::array stands in for the static array。一緒に考えると、メモリ内で連続した素敵な2次元配列が得られ、範囲外になった瞬間に解放されます。

#include <vector> 
#include <array> 

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 
0

'deleteArray'関数を参照してください。あなたはかなりサブ配列を最初に削除する必要があります。次に、最上位配列を削除します。メモリ管理の学習は優れたスキルです。メモリ管理( 'new'と 'delete'を使用)を学ぶと、STLコンテナについて学習する必要があります。実際には、人々はSTLを使用します。

また、印刷機能を追加して、その外観を確認することもできます。

#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; 
} 
関連する問題