2011-07-10 25 views
7

Đối với một dự án trường học, chúng tôi phải gửi các tệp lớn trên mạng., Chúng tôi phải sử dụng Poco :: XML cho dữ liệu của chúng tôi.Làm cách nào để giải quyết rò rỉ bộ nhớ được báo cáo nằm trong chuỗi STL?

Sau khi tệp của chúng tôi được gửi qua mạng, có vẻ như bộ nhớ không miễn phí.

Dưới đây là một ví dụ cho một tập tin của ~9 Mb trên một phần nhận:

valgrind --leak-check=full --show-reachable=yes -v ourExecutable parms lợi nhuận:

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 

Các chức năng mà là ngay trước khi Poco là

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

trong đó kêu gọi

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

(Lưu ý rằng XMLStringstd::string)

Tại sao append của chuỗi STL rò rỉ bộ nhớ?

Nếu tôi chỉ định thay vì sử dụng các nhà xây dựng sao chép, nó sẽ đưa ra cùng một vấn đề.


EDIT:

Tôi đang sử dụng mới nhất ổn định GNU GCC 4.4.4 trên Gentoo x64 (linux-2.6.34-gentoo-r12).

Nhiều chức năng từ các cuộc gọi stack (tước khối không liên quan lớn của mã/nếu cấu trúc):

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

nơi fQueue là:

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

Bạn không hiển thị mã của hàm 'OurExecutable :: handleClientPacket', hoặc bất kỳ mã nào ở trên nó trong ngăn xếp cuộc gọi. Không có hàm nào mà bạn đã đăng hiển thị bất kỳ phân bổ động nào. Vì vậy, rò rỉ không thể ở đó. –

+0

Bạn có tự mình phân bổ bộ nhớ động không? – Marlon

+0

Trình biên dịch nào được sử dụng (và phiên bản của trình biên dịch)? Việc triển khai thư viện chuẩn nào được sử dụng? –

Trả lời

9

Tôi sẽ làm cho nhận xét này, nhưng dường như tôi không có đại diện. Bạn có nhớ làm cho destructor cho Command ảo không? Nếu name hoặc data là các trường của PutCommand thay vì Command và hàm hủy Command không phải là ảo, chúng có thể không được giải phóng đúng cách khi bạn xóa command trong handleClientPacket.

+0

Rất vui khi bạn không đưa ra nhận xét này. Rõ ràng vấn đề thực tế dường như xa nguồn ...:/ –

+0

** Bài học kinh nghiệm: ** Không nhất thiết phải nhìn vào nguồn, cũng thấy nơi nó được lưu trữ và những gì xảy ra với nó. –

Các vấn đề liên quan