2011-07-10 20 views
7

Bir okul projesi için, ağ üzerinden büyük dosyalar göndermeliyiz. Verilerimiz için Poco :: XML kullanmalıyız.STL dizesinde bulunduğu bildirilen bellek sızıntılarını nasıl çözebilirim?

Dosyalarımız ağ üzerinden gönderildikten sonra, belleğin boş olmadığı anlaşılıyor.

valgrind --leak-check=full --show-reachable=yes -v ourExecutable parms döner:

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 

Poco

çağırır

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

sağ öncedir işlevi İşte

alıcı kısmında ~9 Mb bir dosya için bir örnektir
XMLString Element::innerText() const 
{ 
    XMLString result; 
    Node* pChild = firstChild(); 
    while (pChild) 
    { 
     result.append(pChild->innerText()); 
     pChild = pChild->nextSibling(); 
    } 
    return result; 
} 

Neden STL dize append sızıntı bellek (XMLStringstd::string olduğunu unutmayın)?

Sadece kopya oluşturucuları kullanmak yerine atarsam, aynı sorunu verir.


DÜZENLEME:

Ben Gentoo x64 üzerinde son kararlı GNU GCC 4.4.4 (linux-2.6.34-gentoo-r12) kullanıyorum. fQueue olduğu

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

ve

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

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

     delete command; 
} 

ve

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

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

    delete prio; 
} 

: Çağrı yığınından

Diğer fonksiyonlar (kod alakasız büyük parçalar/yapılar halinde soyulmuş)

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

'OurExecutable :: handleClientPacket' işlevinin kodunu ya da herhangi birimin çağrı yığında göstermediniz. Yayınladığınız kodlardan hiçbiri dinamik ayırma göstermiyor. Yani sızıntı orada olamaz. –

+0

Herhangi bir dinamik bellek ayırma işlemini kendiniz mi yapıyorsunuz? – Marlon

+0

Hangi derleyici kullanılır (ve sürümü)? Hangi standart kütüphane uygulaması kullanılır? –

cevap

9

Bunu bir yorum yapardım, ama görünüşe göre temsilcisi yok. Command için yıkıcıyı sanallaştırmayı hatırladın mı? name veya dataPutCommand yerine Command alanları ve Command yıkıcı sanal değilse handleClientPacket yılında command sildiğinizde, bunların düzgün serbest olmayabilir.

+0

Bu yorumu yapmadığına sevindim. Görünüşe göre asıl sorun kaynağından çok uzak görünüyordu ...:/ –

+0

** Alınan ders: ** Kaynağa mutlaka bakmayın, aynı zamanda nerede saklandığını ve onunla ne olduğunu görün. –