2010-11-28 8 views
2

J'ai affaire à des tableaux dynamiques. La fonction empty_matrix() crée un nouveau tableau, représentant une matrice. delete_matrix() libère toute la mémoire, allouée à la matrice.Corriger l'allocation et la mémoire libre pour les tableaux en C++

Est-ce que je reçois une fuite de mémoire dans la fonction example() si j'appelle add(add(a, b), c)? Qu'arrivera-t-il à la mémoire allouée dans la fonction add(...)? Dois-je le libérer? Où devrais-je le faire?

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

Vous pouvez utiliser des outils comme valgrind: http://valgrind.org/ qui peut vous dire qu'il y a des fuites. – Marii

Répondre

5

Ce que vous devriez faire est d'utiliser l'objet Orientation/RAII. Votre membre de données de la classe matrix doit être privé et la mémoire pour cela doit être allouée dans le constructeur et libérée dans le destructeur. De cette façon, vous n'aurez pas à vous soucier des fuites de mémoire.

Par exemple ...

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_; 
}; 

Tout cela, bien sûr, si cela est devoirs. Si ce n'est pas le cas, vous devriez vous abstenir d'utiliser des tableaux dans cette situation. Utilisez std::vector s

+0

En utilisant l'orientation Object, je ne peux pas éviter de libérer la mémoire allouée par la fonction 'add (...)' séparément? Les 'std :: vector's sont-ils aussi rapides que les tableaux? Comment puis-je accéder aux données via 'get (int i, int j)'? – multiholle

+0

@multiholle: Oui, vous éviterez la fuite de mémoire, car l'objet temporaire sera détruit, son destructeur sera appelé et la mémoire sera libérée. Pour savoir comment utiliser le vecteur, voir ce lien: http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027 –

+0

@multiholle: Et oui, les vecteurs sont * presque * aussi rapides que les tableaux. Il y a très peu de situations dans lesquelles la différence est notable. –

2

Oui, vous devrez libérer le résultat d'une empty_matrix ou add appel à l'aide delete_matrix. Vous fuyez la mémoire, car vous ne libérez pas la matrice de l'appel le plus interne add.

1

Vous devriez avoir exactement un new pour un delete et un new[] pour un delete[] dans votre code. C'est le principe le plus important. Par conséquent, si la fonction add crée une nouvelle matrice, elle doit être supprimée quelque part.


En outre, empty_matrix devrait être le constructeur de la classe matrix et delete_matrix devrait être son destuctor.

Vous pouvez également remplacer le data avec un std::vector et votre gestion de la mémoire serait beaucoup plus automatisé, vous soulager de la nécessité de compter new s et delete s.