web-dev-qa-db-ja.com

ポインターのベクトルをクリアする

次のようなクラスを定義したと仮定します。

 class foo {
 private: 
    std::vector< int* > v;
 public:
    ...
    void bar1()
    {
       for (int i = 0; i < 10; i++) {
         int *a = new int;
         v.Push_back( a );
       }
    };

    void bar2()
    {
       std::vector< int >::iterator it = v.begin();
       for ( ; it != v.end(); it++ )  
         std::cout << (*it);
       v.clear();
    }
 };

要するに、ベクター内のいくつかのポインターをプッシュバックし、後でベクターをクリアします。問題は、このコードにメモリリークがあるかどうかです。ベクトルをクリアすると、ポインターは適切に削除されますか?

28
mahmood

はい、ポインタを削除しない限り、コードにはメモリリークがあります。 fooクラスがポインターを所有している場合、それらを削除するのはその責任です。これは、ベクトルをクリアする前に行う必要があります。そうしないと、割り当てを解除する必要があるメモリのハンドルが失われます。

   for (auto p : v)
   {
     delete p;
   } 
   v.clear();

適切な スマートポインターstd::vectorを使用すると、メモリ管理の問題を完全に回避できます。

36
juanchopanza

最短かつ明確な解決策は次のとおりだと思います。

std::vector<Object*> container = ... ;
for (Object* obj : container)
    delete obj;
container.clear();
10
Tim Kuipers

いいえ、ベクターストレージのみをクリアします。 「新規」の割り当てられたメモリはまだあります。

for (int i =0; i< v.size();i++)
   {
     delete (v[i]);
   } 
   v.clear();
7
user349026

for_eachを使用できます:

std::vector<int*> v;

template<typename T>
struct deleter : std::unary_function<const T*, void>
{
  void operator() (const T *ptr) const
  {
    delete ptr;
  }
};

// call deleter for each element , freeing them
std::for_each (v.begin (), v.end (), deleter<int> ());
v.clear ();
3
tozka