2012-04-08 4 views
0

私はstd :: streambufから派生したクラスを持っています。なぜ、どこに漏れているのかわかりません。私が使用しているツールによれば、見た目の前の最後のポイントは、このクラスのどこかにあります(ただし、行番号は取り出せません)。私のカスタムstreambufクラスのメモリリーク

考えられるのは、このクラスは任意の数のstreambufsデータをに同期する。 (例えば、std :: coutとa ofstream.rdbuf)私はすべてのstreambufsに書き込むstd :: endlを得るまで文字列にデータを格納します

誰でも私にできることを教えてくださいリークメモリ?

これは私のヘッダーです:

#ifndef _MY_STREAM_BUF_H 
#define _MY_STREAM_BUF_H 

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

#include "../../../Interface/EngineDefs.h" 

namespace MyEngine 
{ 
    class MyStreamBuf : public std::streambuf 
    { 
    public: 
     MyStreamBuf(); 
     ~MyStreamBuf(); 

     void AddStream(std::streambuf* sb); 
     void RemoveStream(std::streambuf* sb); 
     bool IsStreamAdded(std::streambuf* sb); 

    private: 
     std::list<std::streambuf*> mStreamBufs; 
     std::string mLine; 

     int32_t overflow(int32_t c); 
     int32_t sync(); 

    }; 
} 

#endif 

のcppファイル:

#include "../../../Include/Core/Logging/MyStreamBuf.h" 

namespace MyEngine 
{ 
    MyStreamBuf::MyStreamBuf() : std::streambuf() 
    { 

    } 

    MyStreamBuf::~MyStreamBuf() 
    { 
     mStreamBufs.clear(); 
     mLine.clear(); 
    } 

    void MyStreamBuf::AddStream(std::streambuf* sb) 
    { 
     if (sb) 
      mStreamBufs.push_back(sb); 
    } 

    void MyStreamBuf::RemoveStream(std::streambuf* sb) 
    { 
     if (sb) 
      mStreamBufs.remove(sb); 
    } 

    bool MyStreamBuf::IsStreamAdded(std::streambuf* sb) 
    { 
     if (sb) 
      return (std::find(mStreamBufs.begin(),mStreamBufs.end(),sb) != mStreamBufs.end()); 
     else 
      return false; 
    } 

    int32_t MyStreamBuf::overflow(int32_t c) 
    { 
     int32_t r1 = 0, r2 = 0; 

     if (c == EOF) 
      return !EOF; 
     else 
     { 
      mLine += c; 
      return r1 == EOF || r2 == EOF ? EOF : c; 
     } 
    } 

    int32_t MyStreamBuf::sync() 
    { 
     int32_t res = 0; 

     for(std::list<std::streambuf*>::iterator it = mStreamBufs.begin(); it != mStreamBufs.end(); ++it) 
     { 
      if (*it) 
      { 
       (*it)->sputn(mLine.c_str(),mLine.length()); 
       res &= (*it)->pubsync(); 
      } 
     }    

     mLine.clear(); 

     return res == 0 ? 0 : -1; 
    } 
} 
+1

はあなたのストリームです*動的に割り当てられますか? remove()を呼び出すと、削除が実行されますか? – EdChum

+0

あなたはmStreambufメンバーかMyStreamBufクラスを意味しますか?追加されたstreambufsは例えばstd :: cout.rdbufまたはofstream.rdbufです(私はクローズして削除します) – KaiserJohaan

+0

void MyStreamBug :: RemoveStream(std :: streambuf * sb)に渡されているものはすべてsb動的に割り当てられますか?その場合は、削除する必要がありますので、削除する必要があります。エントリを削除し、ポインタを格納するときに適切な処理をしないでください。そうでない場合は、生ポインタの代わりに 'shared_ptr 'を格納するコンテナを使用する方がよいでしょう。 – EdChum

答えて

1

オブジェクトは破損していません。古典的なメモリリークです。

void MyStreamBuf::RemoveStream(std::streambuf* sb) 
{ 
    delete sb; // need this to flush and avoid leak 

    if (sb) // do you really need to check if it's null? 
     mStreamBufs.remove(sb); 
} 

streambufへのポインタを持つことが所有権を意味するものではありませんので、これは、本当に最適なソリューションではないことに注意してください。たとえば、std::cout.rdbuf()は追加するものですが、deleteにすることはできません。 (あなたのクラスが何をすべきか分かりません)

所有権の意味を決める必要があります。 MyStreamBufはすべてmStreamBufsを所有していますか、または所有していないか、それぞれに所有権フラグを追加してもかまいませんが、すべての所有者はいつでもそのオブジェクトを破棄する必要があります。

+0

私はそれを書いておくべきです。クラスはstreambufsを所有していないので、それらをクリーンアップしてはいけません – KaiserJohaan

-2

あなたがのstd :: streambufのは何の仮想デストラクタを持っていないと考えていますか?実際には(動的多態性を使用する場合)デストラクタは呼び出されません もちろんmStreamBufsの要素は実際には削除されません。

+0

MyStreamBuf、niether〜MyStreamBuf()やそのstreambufでdeleteを呼び出すことはありませんか? – KaiserJohaan

+1

'std :: basic_streambuf'には仮想デストラクタがあります.27.6.3を参照してください。実際、 'std :: streambuf'は機能を実装しておらず、簡単に抽象基本クラスであった可能性があります。 – Potatoswatter

+0

OK、ありがとうございます。通常、私は標準クラス(分解のみ)の継承を使用しませんが、この場合可能です。 –

関連する問題