0

我知道。Xpressive 在这里(可能)没有错,但我付出了很多努力来寻找内存泄漏,我不得不调整代码布局以修复出血。

有人可以向我解释为什么布局的变化修复了它吗?我不明白为什么(正确/改进)使用“static const”可以修复泄漏。

顺便说一句,泄漏发生在 MIP 内核上,使用 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;
}

每次调用 foo! 时似乎都会发生泄漏!

4

1 回答 1

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?您能否发布一个完整的、独立的示例以便我进行调查?更好的是,提交一个错误并将代码附加到那里。谢谢,

埃里克

-----开始原始响应-----

我怀疑您与 xpressive 的循环跟踪代码有冲突。有关在函数局部对象中嵌套全局正则表达式对象的警告,请参见此处。我认为发生的事情是,为了防止悬空引用,函数本地regx必须持有对 的引用token,并且token必须持有对 的(弱)引用regx。正在增长的是token弱引用的地图。这不是严格技术意义上的泄漏,因为内存在token被销毁时会被回收。但这显然并不理想。

不久前,我通过添加对地图的机会主义清除来清除对过期正则表达式的弱引用,从而修复了 xpressive 中的类似“泄漏”。我必须研究为什么在这种情况下没有发生。请在此处提交错误。谢谢。

同时,您的修复非常好。声明函数局部regx静态意味着它只会被构造一次,因此token的弱引用映射永远不会超过大小 1。

于 2012-08-07T19:14:11.963 回答