繁体   English   中英

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

[英]std::string operator+() memory leak?

我很担心,因为我写了一个小应用程序,如果我相信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)

这是有问题的功能:

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

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

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

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

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

引用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中讨论过

我不会太担心STL泄漏。

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

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

我怀疑正在发生的事情是编译器正在使用NRVO将临时字符串放入其实际返回位置。 然后将该返回字符串存储在已分配并从堆中泄漏的对象中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM