“压力泄漏”固定,但不明白
问题描述:
我知道。 Xpressive在这里可能(可能)没有错,但是我在寻找内存泄漏方面付出了很多努力,我不得不调整代码布局来修复出血。“压力泄漏”固定,但不明白
有人可以向我解释为什么布局的改变修复了吗?我不明白为什么(正确/改进)使用“静态常量”来修复泄漏。
顺便说一下,泄漏发生在MIPs核心上,使用boost版本1.49,并与GCC 4.3.3交叉编译。
原始 “筛子” 代码:
// source.cpp
#include <boost/...
cregex token = keep(+set[ alnum|'!'|'%'|'_'|'*'|'+'|'.'|'\''|'`'|'~'|'-']);
cregex more = ...
bool foo(const char * begin, const char * end, size_t& length, std::string& dest)
{
mark_tag name_t(1);
cregex regx = bos >>
icase("name:") >>
(name_t= token) >> eos;
cmatch what;
bool ok = regex_search(begin, end, what, regx);
...
return ok;
}
固定 “不露” 代码:
// header.hpp
#include <boost/...
class Xpr {
public:
static const cregex token;
static const cregex more;
};
// source.cpp
#include "header.hpp"
const cregex Xpr::token = keep(+set[ alnum|'!'|'%'|'_'|'*'|'+'|'.'|'\''|'`'|'~'|'-']);
const cregex Xpr::more = ...
bool foo(const char * begin, const char * end, size_t& length, std::string& dest)
{
mark_tag name_t(1);
static const cregex regx = bos >>
icase("name:") >>
(name_t= Xpr::token) >> eos;
cmatch what;
bool ok = regex_search(begin, end, what, regx);
...
return ok;
}
泄漏似乎在富的每一个呼叫正在发生!
答
编辑:写下面的回应后,我试图重现您的问题,并无法。这是我正在使用的代码。
#include <boost/xpressive/xpressive.hpp>
using namespace boost;
using namespace xpressive;
cregex token = keep(+set[ alnum|'!'|'%'|'_'|'*'|'+'|'.'|'\''|'`'|'~'|'-']);
//cregex more = ...
bool foo(const char * begin, const char * end)
{
mark_tag name_t(1);
cregex regx = bos >>
icase("name:") >>
(name_t= token) >> eos;
cmatch what;
bool ok = regex_search(begin, end, what, regx);
//...
return ok;
}
int main()
{
char const buf[] = "name:value";
while(true)
foo(buf, buf + sizeof(buf) - 1);
}
此代码不会泄漏。是否有可能使用xpressive的早期版本?你能发布一个完整的,自包含的例子,以便我可以进行调查吗?更好的是,提交bug并附上代码。谢谢,
埃里克
-----开始原始响应-----
我怀疑你相抵触xpressive中的cycle tracking code的运行。有关在函数本地嵌套全局正则表达式对象的警告,请参阅here。我认为发生的事情是,为了防止悬空引用,函数本地regx
必须持有对token
的引用,并且token
必须将(弱)引用保留回regx
。不断增长的是token
的弱引用地图。这不是严格的技术意义上的泄漏,因为当token
被破坏时内存将被回收。但这显然不理想。
我在xpressive中修正了一个类似的“泄漏”,通过添加机会性清除映射来清除对过期正则表达式的弱引用。我必须研究为什么在这种情况下不会发生这种情况。请提交bug here。谢谢。
与此同时,您的修复很不错。声明函数本地regx
静态意味着它只会构造一次,所以token
的弱参考地图将永远不会增长到大小1以外。
感谢您花时间做出回应。如果我要发布真实的代码,我的雇主可能不会太感动,对不起。 经过进一步测试后发现,即使在函数“foo”中使用static const也不足以完全阻止泄漏。 但我没有看到来自Xpr类静态const成员(还)的任何泄漏。 我的猜测是迈向MIPS版本的GCC中的一些“流氓软件”。我也**不能**重现“偏离目标” – GreyMattR 2012-08-08 13:43:19