处理异常时内存泄漏

MrB*_*ens 4 c++ memory-leaks exception

我只是从 C 转向 C++,目前正在通过异常切入我的路径。

我很难弄清楚为什么我会在这个简单的程序中出现内存泄漏:

#include <iostream>  /* I/O */
#include <exception> /* exception */
#include <cstdlib>   /* stdlib */

using namespace std;

void Bar()
{
    throw exception();
}

void Foo()
{
    int *ip = new int;

    try
    {
        Bar();    
    }
    catch(exception &e)
    {
        cerr << "Foo: Exception caught: " << e.what() << endl;
        delete ip;
        exit(1);
    }

    delete ip;
}

int main()
{
    Foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我觉得我在这里遗漏了一些重要的东西,但不能指出它。任何的想法?

Valgrind 的输出:

==21857== Memcheck, a memory error detector
==21857== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21857== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==21857== Command: ./a.out
==21857== 
Foo: Exception caught: std::exception
==21857== 
==21857== HEAP SUMMARY:
==21857==     in use at exit: 136 bytes in 1 blocks
==21857==   total heap usage: 3 allocs, 2 frees, 72,844 bytes allocated
==21857== 
==21857== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1
==21857==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21857==    by 0x4ECD8FF: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==21857==    by 0x108CCC: Bar() (ex33.cpp:9)
==21857==    by 0x108D0C: Foo() (ex33.cpp:18)
==21857==    by 0x108DBD: main (ex33.cpp:31)
==21857== 
==21857== LEAK SUMMARY:
==21857==    definitely lost: 0 bytes in 0 blocks
==21857==    indirectly lost: 0 bytes in 0 blocks
==21857==      possibly lost: 136 bytes in 1 blocks
==21857==    still reachable: 0 bytes in 0 blocks
==21857==         suppressed: 0 bytes in 0 blocks
==21857== 
==21857== For counts of detected and suppressed errors, rerun with: -v
==21857== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

For*_*veR 7

你真的不应该在 C++ 中调用 exit 。不会调用本地对象析构函数。并且导致堆栈不会被解开,看起来异常的析构函数也不会被调用。

从标准:

18.1.2 抛出异常时,将控制权转移到最近的具有匹配类型的处理程序(18.3);“nearest”表示紧跟 try 关键字的复合语句或构造函数初始化程序最近被控制线程输入但尚未退出的处理程序

18.1.3 抛出异常复制初始化(11.6, 15.8)一个临时对象,称为异常对象。表示临时值的左值用于初始化在匹配处理程序 (18.3) 中声明的变量。如果异常对象的类型是不完整的类型或指向除 cv void 之外的不完整类型的指针,则程序格式错误。

堆栈未展开:不调用具有自动存储持续时间的变量的析构函数。从这里报价