run*_*us2 10 c++ memory-leaks smart-pointers unique-ptr c++11
我想问一个关于构造函数中的内存泄漏的问题.我们来考虑一个课程:
class Foo
{
public:
Foo(){ throw 500;}
};
Run Code Online (Sandbox Code Playgroud)
有什么区别
std::unique_ptr<Foo> l_ptr = std::make_unique<Foo>();
Run Code Online (Sandbox Code Playgroud)
和
std::unique_ptr<Foo> l_ptr;
l_ptr.reset(new Foo());
Run Code Online (Sandbox Code Playgroud)
在我看来,make_unique的解决方案应该保护我免受内存泄漏,但在这两种情况下我得到了相同的valgrind结果:
$ valgrind --leak-check=full ./a.out
==17611== Memcheck, a memory error detector
==17611== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17611== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17611== Command: ./a.out
==17611==
terminate called after throwing an instance of 'int'
==17611==
==17611== Process terminating with default action of signal 6 (SIGABRT)
==17611== at 0x5407418: raise (raise.c:54)
==17611== by 0x5409019: abort (abort.c:89)
==17611== by 0x4EC984C: __gnu_cxx::__verbose_terminate_handler() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17611== by 0x4EC76B5: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17611== by 0x4EC7700: std::terminate() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17611== by 0x4EC7918: __cxa_throw (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17611== by 0x40097B: Foo::Foo() (in /home/rungo/Repositories/test/a.out)
==17611== by 0x4008DC: main (in /home/rungo/Repositories/test/a.out)
==17611==
==17611== HEAP SUMMARY:
==17611== in use at exit: 72,837 bytes in 3 blocks
==17611== total heap usage: 4 allocs, 1 frees, 72,841 bytes allocated
==17611==
==17611== 132 bytes in 1 blocks are possibly lost in loss record 2 of 3
==17611== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17611== by 0x4EC641F: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==17611== by 0x400963: Foo::Foo() (in /home/rungo/Repositories/test/a.out)
==17611== by 0x4008DC: main (in /home/rungo/Repositories/test/a.out)
==17611==
==17611== LEAK SUMMARY:
==17611== definitely lost: 0 bytes in 0 blocks
==17611== indirectly lost: 0 bytes in 0 blocks
==17611== possibly lost: 132 bytes in 1 blocks
==17611== still reachable: 72,705 bytes in 2 blocks
==17611== suppressed: 0 bytes in 0 blocks
==17611== Reachable blocks (those to which a pointer was found) are not shown.
==17611== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==17611==
==17611== For counts of detected and suppressed errors, rerun with: -v
==17611== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[1] 17611 abort (core dumped) valgrind --leak-check=full ./a.out
Run Code Online (Sandbox Code Playgroud)
当我使用clang ++和g ++时,它是一样的.我在这里找到:https://isocpp.org/wiki/faq/exceptions#ctors-can-throw这句话:
注意:如果构造函数通过抛出异常结束,则清除与对象本身关联的内存 - 没有内存泄漏.
我的问题是为什么我们在这种情况下有泄漏以及为什么make_unique不能防止泄漏(doeas意味着make_unique和reset(new ...)之间没有dofference?
你是否正在捕捉异常?当捕捉异常,Valgrind的(与编译克++ 6.2 -g)检测到没有泄漏都与make_unique和reset.
int main() try
{
#if TEST_MAKE_UNIQUE
std::unique_ptr<Foo> l_ptr = std::make_unique<Foo>();
#else
std::unique_ptr<Foo> l_ptr;
l_ptr.reset(new Foo());
#endif
}
catch(...)
{
}
Run Code Online (Sandbox Code Playgroud)
AddressSanitizer也不报告任何问题.
(PS这是展示不太知名的函数 - try-block语言功能的好机会.)
"为什么内存不会泄露?"
该标准保证在构造期间抛出异常时将自动释放分配有" new表达式"的内存.
如果对象是由new-expression([expr.new])分配的,则调用匹配的释放函数([basic.stc.dynamic.deallocation])(如果有的话)以释放对象占用的存储空间.
相关问题:
| 归档时间: |
|
| 查看次数: |
2894 次 |
| 最近记录: |