2011-07-10 19 views
7

एक स्कूल प्रोजेक्ट के लिए, हमें नेटवर्क पर बड़ी फाइलें भेजनी होंगी, हमें अपने डेटा के लिए पॉको :: एक्सएमएल का उपयोग करना होगा।एसटीएल स्ट्रिंग में रहने के लिए रिपोर्ट की गई मेमोरी लीक को मैं कैसे हल करूं?

हमारी फाइलें नेटवर्क पर भेजने के बाद, ऐसा लगता है कि स्मृति मुक्त नहीं है।

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; 
} 

जो

कहता है

यहाँ प्राप्त ओर से ~9 Mb की एक फ़ाइल के लिए एक उदाहरण है

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

(ध्यान दें कि XMLStringstd::string है)

क्यों एसटीएल स्ट्रिंग के append लीक कर रहा है स्मृति?

अगर मैं सिर्फ कॉपी कन्स्ट्रक्टर का उपयोग करने के बजाय असाइन करता हूं तो यह वही समस्या देता है।


संपादित करें:

मैं Gentoo 64 पर नवीनतम स्थिर जीएनयू जीसीसी 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 वर्चुअल के लिए विनाशक बनाने के लिए याद किया गया है? यदि name या dataके बजाय PutCommand के क्षेत्र हैं और Command विनाशक आभासी नहीं है, तो handleClientPacket में हटाते समय उन्हें ठीक से मुक्त नहीं किया जा सकता है।

+0

खुशी है कि आपने यह टिप्पणी नहीं की है। स्पष्ट रूप से वास्तविक समस्या स्रोत से बहुत दूर लगती थी ...:/ –

+0

** सबक सीखा: ** स्रोत को जरूरी नहीं देखें, यह भी देखें कि यह कहां संग्रहीत हो जाता है और इसके साथ क्या होता है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^