2012-05-10 10 views
1

私はポインタのstd :: listでいくつかのテストをしています。私はリストのいくつかの要素を削除するremove_ifアルゴリズムを使用しています。しかし、私はいくつかの問題に遭遇しました。remove_ifはポインタを破壊しないのでメモリリークを引き起こしています(私は思う)。標準::ポインタとremove_ifのリスト

私は解決策を見つけたが、それがうまく行われた場合、私は知らないが、ここでは正しいか、少なくとも許容...

コードです:

#include <algorithm> 
#include <iostream> 
#include <list> 

using namespace std; 

class Object 
{ 
private: 
     int intData; 
public: 
     Object(int n) : intData(n) { }; 
     int getIntData(void) { return intData; }; 
     void setIntData(int n) { intData = n; }; 
}; 

/** Functor */ 
struct listFunctor 
{ 
bool operator()(Object* obj1, Object* obj2) const 
{ 
    return (obj1->getIntData() < obj2->getIntData()); 
} 
}; 

class removeFunctor 
{ 
private: 
     int remover; 
public: 
     removeFunctor(int n) : remover(n) { }; 
     bool operator()(Object* obj) 
     { 
     bool res = (obj->getIntData() != remover); 

     if(res) 
      delete obj; 

     return res; 
     } 
}; 

typedef list<Object*> objList; 
typedef list<Object*>::iterator objectListIter; 

int main(int argc, char** argv) 
{ 
objList objectList; 

objectList.push_back(new Object(8)); 
objectList.push_back(new Object(0)); 
objectList.push_back(new Object(2)); 

/** sort elements. */ 
objectList.sort(listFunctor()); 

/** print. */ 
for(objectListIter it = objectList.begin(); it != objectList.end(); ++it) 
    cout<<*it<<" "<<(*it)->getIntData()<<'\n'; 

/** remove. */ 
objectListIter iter = remove_if(objectList.begin(), objectList.end(), removeFunctor(8)); 

/** print. */ 
for(objectListIter it = objectList.begin(); it != iter; ++it) 
    cout<<*it<<" "<<(*it)->getIntData()<<'\n'; 

/** delete list. */ 
for(objectListIter it = objectList.begin(); it != iter; ++it) 
    delete *it; 

objectList.clear(); //IS THIS NECESSARY? 

return 0; 
} 

プログラムが最初に作成されますリストを並べ替えると、いくつかの要素が削除されます。

このコードは、この問題に対する有効かつ実行可能な解決策ですか? Valgrindのデフォルトのスキャンでは問題は報告されませんが、私はより多くのテストをしています。

ありがとうございました。

+7

'typedef std :: list > objList;': '不要'が必要です。そして、あなたが本当にポインタを必要としない限り、それらをまったく使用せず、代わりに 'std :: list 'を使用してください。 'delete'は痛みや苦しみにつながります。最後に、リンクリストが本当に必要な場合を除き、 'std :: vector 'が必要です。 –

+0

これは[CodeReview.SE](http://codereview.stackexchange.com/)に適しているようです。 – ildjarn

+0

unique_ptrはコピーできませんので、最初からポインタを格納する必要がある場合は、std :: shared_ptrを使う方がよいでしょう。 – Fredrik

答えて

9

list<Object*>から削除すると、リストからのポインタのみが削除されます。 list<unique_ptr<Object>>またはlist<shared_ptr<Object>>を選択すると、スマートポインタがリストから削除されたときに指されたオブジェクトが自動的に削除されます。

+2

Jamesが言ったように、それらは 'std :: list 'を好んでおり、その前に 'std :: vector 'を好むので。ポインタが少ないほど良い。 – GManNickG