我是智能指针世界的新手。我已经完成了我的阅读,所有人都表示,即使程序在遇到异常后退出,智能指针也会避免泄漏内存。
我写下了一个简单的程序试试这个,但是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)
使用智能指针是否可以保证即使出现异常,也会销毁分配的资源?
答案 0 :(得分:12)
如果没有处理异常,那么它是实现定义的,在调用std::terminate
之前是否将展开堆栈。
如果处理异常,则智能指针将按预期工作。
参考:
C ++ 11 15.5.1 std::terminate()
函数
1在某些情况下,必须放弃异常处理,以获得不那么微妙的错误处理技术。这些情况是:
........
- 当异常处理机制找不到抛出异常的处理程序时,或
........
2在这种情况下调用
std::terminate()
。 在没有找到匹配处理程序的情况下,无论是否在调用std::terminate()
之前展开堆栈,它都是实现定义的。
答案 1 :(得分:5)
当调用std::terminate()
时(就像未捕获的异常一样),不会运行正常清理(至少对于main()
的堆栈帧),因此你可以记忆{已经在该堆栈框架中分配了泄漏,即使它被智能指针管理。当您在std::bad_alloc
中捕获main()
并正常返回时,智能指针将履行它的职责。
答案 2 :(得分:2)
如果未捕获异常,则堆栈展开是特定于实现的。因此,在您的情况下,它不会释放内存。
此外,不再推荐使用auto_ptr。
使用std :: unique_ptr:
unique_ptr<int> ptr_int(new int(5));