2012-08-07 36 views
0

我知道。 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; 
} 

泄漏似乎在富的每一个呼叫正在发生!

回答

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必须将(弱)引用保留回regx。不断增长的是token的弱引用地图。这不是严格的技术意义上的泄漏,因为当token被破坏时内存将被回收。但这显然不理想。

我在xpressive中修正了一个类似的“泄漏”,通过添加机会性清除映射来清除对过期正则表达式的弱引用。我必须研究为什么在这种情况下不会发生这种情况。请提交bug here。谢谢。

与此同时,您的修复很不错。声明函数本地regx静态意味着它只会构造一次,所以token的弱参考地图将永远不会增长到大小1以外。

+0

感谢您花时间做出回应。如果我要发布真实的代码,我的雇主可能不会太感动,对不起。 经过进一步测试后发现,即使在函数“foo”中使用static const也不足以完全阻止泄漏。 但我没有看到来自Xpr类静态const成员(还)的任何泄漏。 我的猜测是迈向MIPS版本的GCC中的一些“流氓软件”。我也**不能**重现“偏离目标” – GreyMattR 2012-08-08 13:43:19