TTb*_*boy 2 c++ string valgrind stl
我没有看到下面泄漏的原因.
#include <iostream>
#include <cstdlib>
int fail(const std::string str)
{
std::cerr<< str << std::endl;
exit(1);
}
const std::string usage()
{
std::string a = "a";
return a;
}
int main()
{
fail(usage());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Valgrind说:
==7238== 14 bytes in 1 blocks are possibly lost in loss record 1 of 1
==7238== at 0x402377E: operator new(unsigned) (vg_replace_malloc.c:224)
==7238== by 0x40E7C03: std::string::_Rep::_S_create(unsigned, unsigned,
std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x40E8864: (within /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x40E89D5: std::string::string(char const*, std::allocator<char> const&)
(in /usr/lib/libstdc++.so.6.0.10)
==7238== by 0x80488EC: usage() (main.cpp:12)
==7238== by 0x804897C: main (main.cpp:18)
==7238== LEAK SUMMARY:
==7238== definitely lost: 0 bytes in 0 blocks.
==7238== possibly lost: 14 bytes in 1 blocks.
==7238== still reachable: 0 bytes in 0 blocks.
==7238== suppressed: 0 bytes in 0 blocks.
Run Code Online (Sandbox Code Playgroud)
问题出在fail()函数中.当它退出()时,内存泄漏.
如果我注释退出(1); 然后没有可能的泄漏.
另外,如果我将签名从int fail(const std :: string str)更改为int fail(const char*str)
那么也没有可能的泄漏.我不喜欢这个解决方案,因为我使用的是fail(string +(LINE))类型的东西,但无论如何,这里发生了什么?
如果有人能解释,我会很高兴.
谢谢!
(upps.在我猜之前问过相同的问题,抱歉!Valgrind在为字符串赋值时报告内存泄漏)
Jam*_*lis 21
调用时exit(),不会调用自动对象(局部变量)的析构函数.
在您的特定示例中,std::string不会调用析构函数,因此std::string永远不会释放其拥有的内存.
如果你fail()拿a const char*,没有泄漏的原因是没有析构函数const char*; 当指针被销毁时,不会释放任何内容.如果指针指向动态分配的内存,那么在程序退出之前必须释放该内存(由您),否则会出现内存泄漏.如果它指向字符串文字,则没有内存泄漏,因为字符串文字具有静态存储持续时间(即,它们在程序的整个生命周期中都存在).
James McNellis已经写了一个正确的答案.但是我想补充一些东西:
以不必调用exit()的方式编写软件总是一件好事 - 这有助于您改进整体设计,指定和理解对象的生命周期(除非是非常特殊的 - 相当低级别的情况......) .
如您所见,这在使用valgrind等工具时非常重要!"干净"的关机程序让您感觉安全,然后一切正常,正如您所期望的那样;)特殊情况下的清洁关机程序应该是每个软件的要求.
您应该考虑throw异常而不是调用某个fail()函数.抛出异常时,堆栈将被展开,因此std::string将调用您案例中的析构函数.