0

私は2つのクラスを持っています。1つは継承し、もう1つは継承しostreamます。streambufこれが私がそれらを使用している方法です

int main () {
   stampstream ss(8,10);
}

スタンプストリーム

stampstream::stampstream(int r, int c) : ostream(new stampbuf(r,c))
{
   std::cout << "I am in stampstream" << std::endl;
}

親 (ostream) クラスの ctor を呼び出して、パラメーターに stampbuf クラスのオブジェクトを作成しているだけです。

スタンプバフ

stampbuf::stampbuf(int r, int c)
: _row(0), _column(0), BUFFER_SIZE(10), _buffer(new char[BUFFER_SIZE]) 
{ //some code }

そのため、プロジェクトで Valgrind を実行すると、106 バイトのメモリ リークがあると表示されます。そのうち 96 件は からnew stampbuf(r,c)、10 件は から来ています_buffer(new char[BUFFER_SIZE])

deleteメモリを解放するために呼び出す Stampbuf のデストラクタがあり_bufferます。ただし、デストラクタは呼び出されません。このメモリ リークを取り除き、stampbuf のデストラクタを呼び出すにはどうすればよいですか?

編集

class stampstream : public ostream {

public:
stampstream(int r, int c);
virtual ~stampstream();
};

class stampbuf : public streambuf {

 public:
stampbuf(int r, int c);
~stampbuf();
virtual int overflow(int ch);
    };
4

3 に答える 3

5

電話する必要があります

delete ostream;

stampstreamandのデストラクタで

delete[] _buffer;

のデストラクタでstampbuf.

std::unique_ptrfor ostreamstd::vectorforを使用したほうがよい_bufferでしょう。メモリ管理について心配する必要はありません。また、ostreamは の名前stdです。手遅れになる前に、変数の名前を変更することをお勧めします。

于 2012-10-16T07:54:11.777 に答える
2

次のように削除できます。

stampstream::~stampstream()
{
    delete rdbuf();
}

ただし、これは安全ではありません。のユーザーはをstampstream変更できる(そして変更する権利がある)ため、rdbuf未定義の動作を引き起こす可能性があります。

慣用的な方法は、派生クラスの対応streambufするメンバーを作成するostreamことです。これにより、動的メモリ割り当てを回避できます。

class stampstream : public ostream {
public:
    // ...
private:
    stampbuf sb;
};

stampstream::stampstream(int r, int c) : ostream(&sb)
{
    // ...
}

// nothing to delete in the destructor...
于 2012-10-16T08:12:37.493 に答える
-1

問題は、ostream がデストラクタでストリーム バッファをクリーンアップしないことです。

http://www.cplusplus.com/reference/iostream/ostream/~ostream/

[...] 関連する streambuf オブジェクトを破棄したり、操作を実行したりしないことに注意してください。

したがって、ストリームバッファを別の場所でクリーンアップする必要があります。最も簡単な方法は、stampbuf オブジェクトを stampstream のメンバー変数にすることです。これにより、stampstream が破棄されると、そのデストラクタが自動的に呼び出されます。

基本クラスの ostream のコンストラクターは、メンバー変数が構築される前に呼び出されるため、ostream のコンストラクターは、stampbuf オブジェクトをパラメーターとして ostream コンストラクターに渡すと、構築されていない stampbuf オブジェクトを参照することになります。そのため、代わりにストリーム バッファをコンストラクタに渡さず、rdbuf を使用して stampbuf を構築した後に、コンストラクタ内に設定します。

http://www.cplusplus.com/reference/iostream/ios/rdbuf/

これは、基本クラスが破壊される前にスタンプバッファが破壊されるという問題を提示するため、ostream のデストラクタは、分解されたスタンプバッファを参照することになります。これは通常は受け入れられませんが、上記の ~ostream のページでは ~ostream がストリーム バッファーに対して何もしないことが保証されているため、この場合は問題ありません。

于 2012-10-16T08:31:21.860 に答える