I
I
iemazurkevich2014-04-16 15:30:31
C++ / C#
iemazurkevich, 2014-04-16 15:30:31

Why is there a memory leak?

Memory leaks are known to occur when seed() throws an exception.
It's just that I don't quite understand why.

void foo( std::shared_ptr< int > p, int init ) {
    *p = init;
}
int seed() {
    //some actions
}
foo( std::shared_ptr< int >( new int( 42 ) ), seed() );

Presumably, the whole point is that the memory for int( 42 ) is allocated, but because of the thrown exception, not only is it not freed, it also remains unrelated to anything.
But I'm not sure it is.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ilya Popov, 2014-04-16
@iemazurkevich

According to the standard, the order of calculations can be different, including the following:

tmp1 = new int(42);
tmp2 = seed();
tmp3 = std::shared_ptr<int>(tmp1);
foo(tmp3, tmp2);

In such a case, if seed throws an exception, a memory leak occurs.
It is to avoid this problem that the make_shared helper function is provided in the standard. The corrected version of your code would look like this:
In addition to being safe, you can also get a performance boost because make_shared can make one memory allocation instead of two.
Additional links:
herbsutter.com/2013/05/29/gotw-89-solution-smart-p...
stackoverflow.com/questions/20895648/difference-in...
As for the order of evaluation, the standard says the following:
[intro.execution] Paragraph 15:
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [ Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note] Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

Thus, the calculation of these tmp1 and tmp2 in our case is unsequenced.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question