我知道。 Xpressive在这里(可能)没有错,但是我已经花了很多心力去寻找内存泄漏,我不得不调整代码布局来修复出血。
有人可以向我解释为什么布局的变化修复了吗?我不明白为什么(正确/改进)使用“static const”来修复泄漏。
BTW,泄漏发生在MIP核心上,使用升级版本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;
}
每次召唤foo时都会发生泄密!
答案 0 :(得分:0)
编辑:写完以下回复后,我尝试重现您的问题而无法做到。这是我正在使用的代码。
#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
必须将(弱)引用保留回{ {1}}。正在增长的是regx
弱引用的地图。这不是严格技术意义上的泄漏,因为当token
被破坏时内存将被回收。但这显然不太理想。
我在xpressive中修复了类似的“泄漏”,通过添加机会清除地图来清除对过期正则表达式的弱引用。我必须研究为什么在这种情况下不会发生这种情况。请提交错误here。感谢。
与此同时,你的修复很好。声明函数本地token
静态意味着它只会被构造一次,因此regx
的弱引用映射将永远不会超过1。