2011-07-10 31 views
7

對於一個學校項目,我們必須通過網絡發送大文件,我們必須使用Poco :: XML來處理我們的數據。如何解決報告駐留在STL字符串中的內存泄漏?

當我們的文件通過網絡發送後,看起來內存不空閒。

下面是的~9 Mb在接收部分的文件的一個示例:

valgrind --leak-check=full --show-reachable=yes -v ourExecutable parms回報:

12,880,736 bytes in 37 blocks are definitely lost in loss record 101 of 101 
    at 0x4C2747E: operator new(unsigned long) (vg_replace_malloc.c:261) 
    by 0x5A3AC88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13) 
    by 0x5A3BC4A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13) 
    by 0x5A3C1BB: std::string::reserve(unsigned long) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13) 
    by 0x5A3C68E: std::string::append(std::string const&) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13) 
    by 0x5202359: Poco::XML::Element::innerText() const (in /home/tomwij/IGS/trunk/Project/external/lib/libPocoXML.so.8) 
    by 0x4145BF: NodeProtocol::getChildNodeStrValue(Poco::XML::Element*, std::string) (NodeProtocol.cpp:82) 
    by 0x41544F: NodeProtocol::deserialize(std::string const&) (NodeProtocol.cpp:200) 
    by 0x40B088: Node::handleClientPacket(PriorityElement*) (Node.cpp:760) 
    by 0x40A04C: Node::handlePackets() (Node.cpp:574) 
    by 0x4078EA: Node::run() (Node.cpp:162) 
    by 0x40772D: Node::activate() (Node.cpp:138) 

LEAK SUMMARY: 
    definitely lost: 12,888,036 bytes in 190 blocks 
    indirectly lost: 644,979 bytes in 1,355 blocks 
     possibly lost: 10,089 bytes in 27 blocks 
    still reachable: 306,020 bytes in 43 blocks 
     suppressed: 0 bytes in 0 blocks 

的函數,它是正確的前波索是

const string NodeProtocol::getChildNodeStrValue(Element * elem, string child) 
{ 
    Element* tempNode = elem->getChildElement(child); 
    XMLString result(tempNode->innerText()); 
    string ret = string(fromXMLString(result)); 
    result.clear(); 
    return ret; 
} 

它調用

XMLString Element::innerText() const 
{ 
    XMLString result; 
    Node* pChild = firstChild(); 
    while (pChild) 
    { 
     result.append(pChild->innerText()); 
     pChild = pChild->nextSibling(); 
    } 
    return result; 
} 

(注意XMLStringstd::string

爲什麼STL字符串append泄漏內存?

如果我只是分配而不是使用複製構造函數,它會給出同樣的問題。


編輯:

我使用的Gentoo上64最新的穩定GNU GCC 4.4.4(Linux的2.6.34-的Gentoo-R12)。

從調用堆棧更多的功能(剝離/代碼無關的大塊如果結構):

Command * NodeProtocol::deserialize(const string & msg) 
{ 
    DOMParser xmlParser; 

    // Get the root node. 
    AutoPtr<Document> doc = xmlParser.parseString(msg); 
    AutoPtr<Element> rootElement = doc->documentElement(); 

    string root = fromXMLString(rootElement->nodeName()); 
    string name = getChildNodeStrValue(rootElement, "name"); 
    string data = getChildNodeStrValue(rootElement, "data"); 
    return new PutCommand(name, data); 
} 

void Node::handleClientPacket(PriorityElement * prio) 
{ 
     Command * command = NodeProtocol::deserialize(prio->fPacket); 

     // CUT: Access some properties of command, let the command execute. 

     delete command; 
} 

void Node::handlePackets() 
{ 
    PriorityElement * prio = fQueue->top(); 
    fQueue->pop(); 

    if (prio->fSource == kCLIENT) 
     handleClientPacket(prio); 
    else if (prio->fSource == kNODE) 
     handleNodePacket(prio); 

    delete prio; 
} 

其中fQueue是:

priority_queue< PriorityElement*, vector<PriorityElement*>, ComparisonFunction > 
+2

您沒有顯示'OurExecutable :: handleClientPacket'函數的代碼,或者它在調用堆棧中的任何代碼。您所發佈代碼的功能都不顯示任何動態分配。所以泄漏不能在那裏。 –

+0

你自己做動態內存分配嗎? – Marlon

+0

使用什麼編譯器(及其版本)?使用什麼標準庫實現? –

回答

9

我會讓這個評論,但顯然我沒有代表。你有沒有想過讓Command虛擬的析構函數?如果namedataPutCommand而不是CommandCommand析構函數不是虛擬的,則在刪除commandhandleClientPacket時,它們可能無法正確釋放。

+0

很高興你沒有對此發表評論。顯然實際的問題似乎離源頭很遠......:/ –

+0

**經驗教訓:**不一定要看源代碼,也可以看看它的存儲位置和發生的情況。 –