【发布时间】:2012-04-21 11:01:02
【问题描述】:
我有一个派生自 std::streambuf 的类。我无法弄清楚它为什么或在哪里泄漏;根据我使用的工具,我的代码在它看起来之前的最后一点是在这个类的某个地方(但它不能提取行号)
这个想法是,该类可以保存将数据同步到的任意数量的流缓冲区。 (例如,std::cout 和 a 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;
}
}
【问题讨论】:
-
您的 streamBuf* 是动态分配的吗?我看到一个对 remove() 的调用,这会执行删除吗?
-
您是指 mStreambuf 成员还是 MyStreamBuf 类?添加的流缓冲区例如 std::cout.rdbuf 或 ofstream.rdbuf (我关闭并删除)
-
我的意思是传递给
void MyStreamBug::RemoveStream(std::streambuf* sb)的任何东西都是动态分配的?如果是这样,那么您应该删除它,因为 remove 只是删除条目而不是在存储指针时执行适当的操作,否则最好有一个容器存储shared_ptr<std::streambuf*>而不是原始指针 -
是的,例如 std::ofstream,我正在正确分配/解除分配
-
它在哪里被释放,我只看到对
remove()的调用而没有对应的delete?你可以做的另一件事是使用windbg,使用gflags在你的应用程序上启用用户堆栈跟踪,然后用windbg将它附加到你的应用程序,输入.symfix;.reload;!heap -l;它应该告诉你它认为泄漏在哪里或在下面运行你的应用程序Visual Studio 并在检测到泄漏时附加 Windbg,请参阅cfc.kizzx2.com/index.php/…
标签: c++ memory-management memory-leaks iostream