C ++异常的情况下,泄漏甚至通过使用智能指针(C++ leaks in case of excep

2019-09-16 10:53发布

我是新来的智能指针世界。 我已经做了我的阅读,他们都表示,智能指针会避免即使泄漏内存时,程序将遇到异常后退出。

我写下了一个简单的程序尝试了这一点,但Valgrind的告诉我我的程序正在泄漏内存(三级allocs和一个自由)。

这是源代码:

#include <iostream>
#include <memory>

using namespace std;

int main()
{
    auto_ptr<int> ptr_int(new int(5));

    throw std::bad_alloc();

    cout << *ptr_int;
}

这Valgrind的报告:

==27862== Memcheck, a memory error detector
==27862== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==27862== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==27862== Command: ./smart_pointers
==27862== Parent PID: 5388
==27862==
==27862==
==27862== HEAP SUMMARY:
==27862==     in use at exit: 104 bytes in 2 blocks
==27862==   total heap usage: 3 allocs, 1 frees, 120 bytes allocated
==27862==
==27862== 4 bytes in 1 blocks are still reachable in loss record 1 of 2
==27862==    at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==27862==    by 0x804878A: main (smart_pointers.cpp:8)
==27862==
==27862== 100 bytes in 1 blocks are possibly lost in loss record 2 of 2
==27862==    at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==27862==    by 0x40E861A: __cxa_allocate_exception (in /usr/lib/libstdc++.so.6.0.14)
==27862==    by 0x80487AE: main (smart_pointers.cpp:10)
==27862==
==27862== LEAK SUMMARY:
==27862==    definitely lost: 0 bytes in 0 blocks
==27862==    indirectly lost: 0 bytes in 0 blocks
==27862==      possibly lost: 100 bytes in 1 blocks
==27862==    still reachable: 4 bytes in 1 blocks
==27862==         suppressed: 0 bytes in 0 blocks
==27862==
==27862== For counts of detected and suppressed errors, rerun with: -v
==27862== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 8)

是否使用智能指针保证分配的资源将被破坏,即使异常显示出来?

Answer 1:

std::terminate()被调用(如对于未捕获的异常的情况下),正常清理不运行(至少对于堆栈帧main()你在那所分配的,因此内存堆栈帧泄漏,即使它理应由智能指针管理。 当你追赶std::bad_allocmain() ,并正常返回,智能指针会做它的职责。



Answer 2:

如果一个异常没有被处理,那么它的实现定义堆栈是否将调用之前展开std::terminate

如果处理异常,则智能指针会按预期工作。

参考:

C ++ 11 15.5.1 std::terminate()函数

1在某些情况下,异常处理必须放弃较少微妙错误处置技术。 这些情况是:

........

- 当异常处理机制找不到抛出的异常的处理程序,或

........

2在这种情况下std::terminate()被调用。 在不匹配的处理器被发现的情况下,它是实现定义堆栈是否被之前展开std::terminate()被调用



Answer 3:

如果异常没有被捕获,那么堆栈展开是特定的实现。 因此,在你的情况下,它不会释放内存。

此外,不再推荐auto_ptr的。

使用std ::的unique_ptr:

unique_ptr<int> ptr_int(new int(5));


文章来源: C++ leaks in case of exception even by using smart pointers