0

std::streambuf から派生したクラスがあります。ただし、なぜ、どこで漏れているのかわかりません。私が使用しているツールによると、コードの最後のポイントは、このクラスのどこかにあります (ただし、行番号を抽出することはできません)。

クラスは、データを同期するストリームバッファをいくつでも保持できるという考え方です。(たとえば、std::cout と ofstream.rdbuf) すべての streambuf に書き込む 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;
    }
}
4

2 に答える 2

1

オブジェクトを破棄していないstreambufため、これは古典的なメモリ リークです。

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

これは実際には最適な解決策ではないことに注意してください。a へのポインタを持つstreambufことは所有権を意味しないからです。たとえば、std::cout.rdbuf()追加したいものではなく、追加したいものかもしれませんdelete。(あなたのクラスが何をすべきかわかりません。)

所有権のセマンティクスを決定する必要があります。MyStreamBufすべての を所有するかmStreamBufs、何も所有しないか、またはそれぞれに所有権フラグを追加するかのいずれかですが、いずれにせよ、すべての所有者はある時点でそのオブジェクトを破棄する必要があります。

于 2012-04-09T02:32:22.143 に答える
-2

std :: streambufには仮想デストラクタがないと思いますか?実際には(動的ポリモーフィズムを使用する場合)、デストラクタは呼び出されません。もちろん、mStreamBufsの要素は実際には削除されません。

于 2012-04-08T22:20:09.653 に答える