简体   繁体   English

处理异常时 Memory 泄漏

[英]Memory leak while handling exceptions

I just move to C++ from C, and currently slicing my path through exceptions.我只是从 C 转到 C++,并且目前正在通过异常来分割我的路径。

I'm having a hard time figuring out why am I getting a memory leak in this simple program:我很难弄清楚为什么在这个简单的程序中会出现 memory 泄漏:

#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;
}

I feel like I'm missing something crucial here, but can't point at it.我觉得我在这里遗漏了一些重要的东西,但不能指出它。 Any idea?任何想法?

Valgrind's output: Valgrind 的 output:

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

You should't call exit in C++ really.你真的不应该在 C++ 中调用 exit 。 Local objects destructors will not be called.不会调用本地对象析构函数。 And cause stack will not be unwounded, looks like destructor of exception also will not be called.并且导致堆栈不会被解开,看起来异常的析构函数也不会被调用。

From standard:从标准:

18.1.2 When an exception is thrown, control is transferred to the nearest handler with a matching type (18.3); 18.1.2 当抛出异常时,控制权转移到最近的具有匹配类型的处理程序(18.3); “nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited “最近的”是指 try 关键字后面的复合语句或 ctor-initializer 最近由控制线程进入但尚未退出的处理程序

18.1.3 Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object. 18.1.3 抛出异常复制初始化 (11.6, 15.8) 临时 object,称为异常 object。 An lvalue denoting the temporary is used to initialize the variable declared in the matching handler (18.3).表示临时值的左值用于初始化匹配处理程序 (18.3) 中声明的变量。 If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than cv void the program is ill-formed.如果异常 object 的类型是不完整类型或指向除 cv void 以外的不完整类型的指针,则程序格式错误。

Stack is not unwound: destructors of variables with automatic storage duration are not called.堆栈未展开:不调用具有自动存储持续时间的变量的析构函数。 Quote from here这里引用

As it turned out, replacing exit(1) from within Foo() to return;事实证明,从Foo()中替换exit(1) ) 以return; fixed the memory leak.修复了 memory 泄漏。

So, my follow-up question, why can't I call exit() from Foo() ?所以,我的后续问题,为什么我不能从Foo()调用exit() ) ?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM