9

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

我写了一个简单的程序来试试这个,但Valgrind告诉我我的程序正在泄漏内存(三个分配,只有一个空闲)。

这是源代码:

#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)

使用智能指针是否保证即使出现异常也会销毁分配的资源?

4

3 回答 3

12

如果未处理异常,则在调用之前是否解开堆栈由实现定义std::terminate

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

参考:

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

1 在某些情况下,必须放弃异常处理以使用不太微妙的错误处理技术。这些情况是:

...........

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

...........

2 在这种情况下std::terminate()被调用。在没有找到匹配处理程序的情况下,在调用之前是否展开堆栈是实现定义的std::terminate()

于 2012-04-10T14:59:21.710 回答
5

std::terminate()被调用时(就像未捕获的异常的情况一样),不会运行正常的清理(至少对于 的堆栈帧main()),因此您在该堆栈帧中分配的内存泄漏,即使它应该是管理的通过智能指针。当您赶上并正常返回std::bad_allocmain(),智能指针将尽其所能。

于 2012-04-10T14:59:49.213 回答
2

如果未捕获到异常,则堆栈展开是特定于实现的。因此,在您的情况下,它不会释放内存。

此外,不再推荐使用 auto_ptr。

使用 std::unique_ptr :

unique_ptr<int> ptr_int(new int(5));
于 2012-04-10T15:03:57.207 回答