我的自定义streambuf类中的内存泄漏

时间:2012-04-08 22:12:21

标签: c++ memory-management memory-leaks iostream

我有一个派生自std :: streambuf的类。我无法弄清楚为什么或泄漏的地方;根据我正在使用的工具,我看到代码之前的最后一点是在这个类中的某个地方(但它不能提取行号)

这个想法是该类可以容纳任何数量的streambufs,它将数据同步到。 (例如,std :: cout和ofstream.rdbuf)我将我的数据存储在一个字符串中,直到我得到std :: endl,我写入所有的streambufs

有人能指出我可以泄漏记忆的地方吗?

这是我的标题:

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

2 个答案:

答案 0 :(得分: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);
}

请注意,这不是一个真正的最佳解决方案,因为指向streambuf的指针并不意味着所有权。例如,std::cout.rdbuf()可能是您要添加的内容,但不是您想要delete的内容。 (我不知道你的班级应该做什么。)

您需要确定所有权语义。 MyStreamBuf拥有所有mStreamBufs,或者它没有,或者您可以为每个添加所有权标志,但无论如何每个所有者都需要在某个时刻销毁其对象。

答案 1 :(得分:-2)

你认为std :: streambuf没有虚拟析构函数吗?实际上(如果你将使用动态多态)你的析构函数将不会被调用 当然,mStreamBufs的元素确实没有被删除..