2010-11-28 16 views
2

私は動的配列を扱っています。関数empty_matrix()は、行列を表す新しい配列を作成します。 delete_matrix()は、行列に割り当てられたすべてのメモリを解放します。C++の配列の正しい割り当てと空きメモリ

私はadd(add(a, b), c)を呼び出した場合、機能example()でメモリリークが発生しますか?関数add(...)に割り当てられたメモリはどうなりますか?私はそれを解放する必要がありますか?私はどこでそれをするべきですか?

matrix empty_matrix(int dim) { 
matrix m; 
m.dim = dim; 
m.data = new int*[dim]; 
for (int i = 0; i < dim; i++) 
    m.data[i] = new int[dim]; 

return m; 
} 

void delete_matrix(matrix m) { 
for (int i = 0; i < dim; i++) 
    delete [] m.data[i]; 
delete [] m.data; 
} 

matrix add(matrix a, matrix b) { 
matrix c = empty_matrix(a.dim); 
for (int i = 0; i < a.dim; i++) 
    for (int j = 0; j < a.dim; j++) 
    c.data[i][j] = a.data[i][j] + b.data[i][j]; 

return c; 
} 

void example() { 
matrix a = empty_matrix(100); 
matrix b = empty_matrix(100); 
matrix c = empty_matrix(100); 

// some modifications of a, b and c 
// ... 

matrix d = add(add(a, b), c); 
print_matrix(d); 

delete_matrix(a); 
delete_matrix(b); 
delete_matrix(c); 
delete_matrix(d); 
} 
+1

valgrind:http://valgrind.org/のようなツールを使用すると、そこにリークがあることがわかります。 – Marii

答えて

5

やるべきことはオブジェクト指向/ RAIIを使用しています。行列クラスのデータメンバーはプライベートでなければならず、そのためのメモリはコンストラクタに割り当てられ、デストラクタで解放される必要があります。この方法で、メモリリークを心配する必要はありません。例えば

...

class matrix 
{ 
public: 
     typedef int element_type; 
     matrix(int dimension) 
      :data_(new element_type[dimension*dimension]) 
     { 

     } 
     //Do define your copy-constructor and assignment operators 
     ~matrix() 
     { 
     delete [] data_; 
     } 

private: 
     element_type* data_; 
}; 

このすべては、もちろん、これは宿題である場合。そうでなければ、この状況では配列の使用を控えてください。 std::vector s

+0

オブジェクトの向きを使用すると、 'add(...)'関数によって割り当てられたメモリを別々に解放することはできませんか? 'std :: vector'は配列と同じくらい速いですか? 'get(int i、int j)'を介してデータにアクセスするにはどうしたらいいですか? – multiholle

+0

@multiholle:一時オブジェクトがdestroyesになり、デストラクタが呼び出されメモリが解放されるため、メモリリークを回避できます。ベクトルの使い方については、このリンクを参照してください。http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027 –

+0

@multiholle:ベクトルは配列と同じくらい速いです。その違いが目立つ状況はほとんどありません。 –

2

はい、empty_matrixまたはaddコールの結果をdelete_matrixで解放する必要があります。最も内側のaddコールの行列を解放していないので、メモリがリークしています。

1

deleteには1つだけnew、コードにはdelete[]のいずれか1つがnew[]である必要があります。それが最も重要な原則です。

したがって、関数addが新しい行列を作成する場合は、どこかで削除する必要があります。


また、empty_matrixmatrixクラスのコンストラクタであるべき、とdelete_matrixはそのdestuctorでなければなりません。

またnew sおよびdelete秒をカウントする必要性からあなたを軽減、はるかに自動化されただろうstd::vectorとあなたのメモリ処理とdataを置き換えることができます。