std :: string operator +()内存泄漏?

mor*_*ndg 13 c++ string valgrind memory-leaks stl

我很担心,因为我写了一个小应用程序,如果我相信valgrind(我实际上做了什么),似乎存在内存泄漏:

==9321== 251 bytes in 7 blocks are definitely lost in loss record 1 of 1
==9321==    at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255)
==9321==    by 0x40D3D05: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.13)
==9321==    by 0x40D4977: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) (in /usr/lib/libstdc++.so.6.0.13)
==9321==    by 0x40D57AC: std::string::reserve(unsigned int) (in /usr/lib/libstdc++.so.6.0.13)
==9321==    by 0x40D5EE6: std::string::operator+=(char) (in /usr/lib/libstdc++.so.6.0.13)
==9321==    by 0x804E113: xl2::TextParser::getNextLfLine() (TextParser.cpp:162)
==9321==    by 0x804BFD5: xl2::UsbTree::parseStringInfo(xl2::TextParser&, std::string&, std::string&) (UsbTree.cpp:362)
==9321==    by 0x804B881: xl2::UsbTree::parseDevicesFile(std::string) (UsbTree.cpp:204)
==9321==    by 0x804B34E: xl2::UsbTree::updateTree() (UsbTree.cpp:70)
==9321==    by 0x804E2E4: scan(std::string) (testUsbTree.cpp:75)
==9321==    by 0x804E6CC: executeCommand(std::string) (testUsbTree.cpp:132)
==9321==    by 0x804E8F6: hushLoop() (testUsbTree.cpp:153)
Run Code Online (Sandbox Code Playgroud)

这是有问题的功能:

/**
 * Returns the next line separated by UNIX style LF
 * @return The next line separated by UNIX style LF
 */
std::string TextParser::getNextLfLine()
{
    std::string line;   // The builded line

    while(this->hasMoreToken())
    {
        line += this->m_pText[this->m_iTokenLocation++];

        // Check if we have just seen a CR/LF character
        if(this->m_pText[this->m_iTokenLocation - 1] == '\n')
            return line;
    }

    return line;
}
Run Code Online (Sandbox Code Playgroud)

程序通过保留主函数(没有调用exit())正确终止.

我只是不明白为什么会有内存泄漏.当我的字符串被复制到堆栈中时,原来的字符串应该在函数离开时被清除,对吗?或者错误可能更高?在顶层我还将返回的值分配给一个局部变量,然后将该场变量作为字段放入对象(通过复制)...

所以我想知道泄漏是来自标准库还是valgrind,这真的很令人惊讶!

任何指向不泄露内存的指针都非常感激:-p!

Cub*_*bbi 10

引用Valgrind FAQ

使用GCC 2.91,2.95,3.0和3.1,使用带有-D__USE_MALLOC的STL编译所有源.谨防!从版本3.3开始,这已从GCC中删除.

使用GCC 3.2.2及更高版本,您应该在运行程序之前导出环境变量GLIBCPP_FORCE_NEW.

使用GCC 3.4及更高版本,该变量已将名称更改为GLIBCXX_FORCE_NEW.

也在GCC FAQ中讨论过


Mat*_* M. 8

我不会太担心STL泄漏.

默认的STL分配器(用于gcc)使用巧妙的技巧来最大化Valgrind经常报告泄漏的效率.值得注意的是它汇集了内存,这意味着它在您清除a时会保留内存,string并且可能在下次插入map或重新插入时重用它vector.

我不认为池本身在程序结束时被妥善处理,可能是为了避免静态破坏命令Fiasco(即,想象池被处理掉然后你请求内存,urk).因此它泄漏...在程序结束之前,操作系统强行恢复内存.