2012-08-07 37 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