Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak while handling exceptions

I just move to C++ from C, and currently slicing my path through exceptions.

I'm having a hard time figuring out why am I getting a memory leak in this simple program:

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

==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)
like image 590
MrBens Avatar asked Mar 02 '23 12:03

MrBens


1 Answers

You should't call exit in C++ really. 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); “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

18.1.3 Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object. An lvalue denoting the temporary is used to initialize the variable declared in the matching handler (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.

Stack is not unwound: destructors of variables with automatic storage duration are not called. Quote from here

like image 116
ForEveR Avatar answered Mar 16 '23 15:03

ForEveR