Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,

I was asked the below in an interview

C++
void f(shared_ptr<int>, int);
int g();
 
void bad()
{
    f(shared_ptr<int>(new int(2)), g());
}


Question was, what is the potential bug in funcion f()? I was absolutely stumped by it. Can anyone explain to me?

I've stepped through code that uses function calls as parameters for the temporaries that will be created in the line f() when it is called. In this case I know it will initialize the auto_ptr before it calls g().

Thanks for any input!
Posted
Updated 6-Apr-11 8:03am
v2
Comments
Albert Holguin 6-Apr-11 14:06pm    
NOW i can see what shared_ptr is! :)
Chris Meech 6-Apr-11 15:47pm    
Might have been better for the interviewer to have just simply asked, "Are you familiar or experienced in using the boost libraries.".
bob_bobber2005 6-Apr-11 17:03pm    
I agree. In fact I know its good practice in C++ to write code such that you avoid the creation of temporaries as Scott Meyers suggests in his "More Effective C++". If the arguments were created before the function call this bug would never arise in the first place. Probably goes to show inexperience of the interviewers.

The pointer you're passing in could be reset/destroyed before the function f is ready for it to be destroyed.

Look up shared_ptr on google for a complete synopsis.
 
Share this answer
 
Comments
bob_bobber2005 6-Apr-11 13:51pm    
How cheeky is that!! They blatantly just copied the question from Boost!! But thats for the hint! :)
Albert Holguin 6-Apr-11 13:59pm    
I didn't even know about shared_ptr(), I frankly don't understand why so many people want automatic deallocation of memory you've allocated yourself, what's wrong with cleaning up after yourself?.. rant...lol
Albert Holguin 6-Apr-11 14:02pm    
my 5 btw
The problem resides in the fact that the C++ language doesn't specify the parameter evaluation order.

Depending on your compiler, you can have sequence like:
1) new int called
2) g() called
3) temporary shared_ptr constructed
4) f called

now, if g() throws, you're left with a new int no shared_ptr still took ownership and that cannot be deleted anymore.

It is also true that, on traditional compilers, parameters are evaluated deep_first or deep_last, so the call to g() will not go in between 1 & 3, but on multi-core system, an optimizing compiler, after detecting that g() is a "pure function" (no access to global variables) may decide to give i to another thread, so it can -effectively- interleave the new int and shared_ptr aggregation process.

It is a "subtle bug" that can stay silent for years, and suddenly appear when this code is moved on another compiler, may be on another platform.

Note that the "problem" is not related to shared_ptr (or auto_ptr or whatever) but to the non predictable sequence of the involved operations.
 
Share this answer
 
v2
Comments
CPallini 7-Apr-11 4:12am    
Good, my 5.
Nuri Ismail 7-Apr-11 4:35am    
Very good explanation, my 5.
bob_bobber2005 7-Apr-11 6:27am    
Brilliant, thanks !
:)
Since the implementation of the function f is not available, it will be kind of hard to suggest what the potential bug in f is!

However, as is, your code allocates some ints and then does not deallocate them. That's a big no-no in my books. :)
 
Share this answer
 
Comments
bob_bobber2005 6-Apr-11 13:44pm    
I did ask them about the implementation on f() and g() but they said it does not matter. There is a bug in there.... been "bugging" me for weeks!
bob_bobber2005 6-Apr-11 13:45pm    
The auto_ptr will deallocate the int on the heap. It's a smart ptr so you don't explicitly need to invoke the destructor.
Emilio Garavaglia 7-Apr-11 6:36am    
You cannot say that,if you don't know what shared_ptr does in it's destructor and copy/assignment.
Chris Meech 7-Apr-11 7:55am    
Well actually I can say it. But you are correct that without an understanding of the boost libraries, the comment may have little or no value. That was the reason for my other comment. The real question would have been better put as to what is your experience with boost. :)
Emilio Garavaglia 7-Apr-11 8:27am    
Not properly ... shared_ptr is now part of the standard library. But the point is another: whenever I write something(new classname(...)), is "something" is a class, the fact I have to take care or not of the newly created object destruction or not depends on the semantic of "something". Whatever book says this is "a big no-no", is not telling the true (and -probably- it has been written by a C programmer!)

This is generallu valid for whatever
<pre>f(g(new A),h())</pre>
if g(A*) takes care of the delete in its own body, but h() evaluation can interrupt the flow between new A and g(*)... you've exactly the same problem. And there's no boost, here!
bad thing about pseudo code questions... it has a few problems (no error checking on function calls, potential memory leak, is shared_ptr() a function or a definition? if its a definition, then new int(2) has to be cast to that type)! ...but the potential memory leak is the most obvious
 
Share this answer
 
Comments
Albert Holguin 6-Apr-11 14:02pm    
thanks to john for pointing out the shared_ptr class template problem... as you can tell, i don't use boost... :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900