2011-07-10 29 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

**经验教训:**不一定要看源代码,也可以看看它的存储位置和发生的情况。 –