Sign in to follow this  

How smart is a smart pointer?

This topic is 2655 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

think my question is stupid, but I can't find the solution for it by myself.

The thing is: Imagine I have this huge, bloated class called GAME_ENGINE.

if in my main.cpp I create a smart_ptr holding GAME_ENGINE, I know that its resources will be released after the main f() is finished.

The question is, just imagine that this huge class is implemented in term of raw ptrs (pointing to things in the 'heap' and in the 'stack') and instantiations of normal classes.

where would the GAME_ENGINE data be located? its implementation has things that normally would either be in the heap or in the stack, but i'm initializing it in the heap and holding it by a smart_ptr. When the smart_ptr is deallocated, the internal data that GAME_ENGINE points too will leak or it will be released?

I know that this scenario is stupid, bad designed, etc, etc. but what would happen in such situation?

Thanks!

Share this post


Link to post
Share on other sites
smart_ptr isn't as smart as you are hoping. All that happens with a smart_ptr is that when it goes out of scope, it will automatically call delete on the pointer that it owns. So it will delete your GAME_ENGINE object. However, it is still your responsibility to clean up any resources owned by GAME_ENGINE. If GAME_ENGINE holds smart_ptrs to its resources, then they too will automatically be cleaned up by their smart_ptr containers. But if you are holding raw pointers and not calling delete, there is no magic that will cause those not to leak just because the GAME_ENGINE pointer is wrapped inside a smart_ptr.

Share this post


Link to post
Share on other sites
If the big game engine class has raw pointers and you are not releasing them with delete then they will leak, holding the game engine class with a shared_ptr doesn't released the memory allocated by it's members.

The shared_ptr is just a wrapper class around a raw pointer which calls the destructor when the shared_ptr falls out of scope.

Share this post


Link to post
Share on other sites
To simplify a bit, a smart_ptr is just a raw pointer that knows when it can safely delete itself. A smart_ptr being released won't have any magical effects that simply deleteing a raw pointer wouldn't.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
A smart_ptr being released won't have any magical effects that simply deleteing a raw pointer wouldn't.


There is no "smart_ptr". The term "smart pointer" is general; we should be clear about which one we're talking about.

But yes, in general, the net effect of using a smart pointer is, generally, that the pointed-at thing gets 'delete'd at the appropriate time, which in turn calls its destructor.

Some smart pointers will allow you to override this behaviour, but you still have to tell them what to do (i.e. supply a custom "do this when it's time to clean up" function).

Share this post


Link to post
Share on other sites
I just assumed he was using one called smart_ptr. It's not like there's some Universal Law of Smart Pointers that says you can't name one that... I had assumed he was planning on rolling his own, calling it that, and wanted to know how they work?

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
I just assumed he was using one called smart_ptr. It's not like there's some Universal Law of Smart Pointers that says you can't name one that... I had assumed he was planning on rolling his own, calling it that, and wanted to know how they work?


:D
actually I'm planning to use the STL's one. But I can never remember its name. But I was thinking with smart_ptr generally, with the 'usual' characteristics a smart pointer should have. Note that I don't have (I think! I hope!) doubts about the smart pointer itself, but the data inside the classes it refers to.

Share this post


Link to post
Share on other sites
The only smart pointer defined in the C++ standard library (please do not say "STL"; that has not been a meaningful term for many years) is std::auto_ptr. You almost certainly do not want to be using std::auto_ptr for whatever it is you think you want to use it for. Its applicability is quite limited. In particular, you may not store them in a standard library container such as std::vector.

You really should think about what smart pointer you want. Start by thinking about why you want a smart pointer.

Share this post


Link to post
Share on other sites
in the specific case talked about here, these two (bare with me, haven't written c++ in years) are identical (except for exception safety, as pointed out below):


int main()
{
GAME_ENGINE* engine = new GAME_ENGINE();
engine->run();
delete engine;
}


and


int main()
{
boost::smart_ptr<GAME_ENGINE> engine(new GAME_ENGINE())
engine-run();
}


in this specific case, the std::auto_ptr would even work, but i normally tried to never touch it. it's like goto, something to better not use in general code (but in specific cases it can fit).

[Edited by - davepermen on September 3, 2010 7:04:51 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by davepermen
in the specific case talked about here, these two (bare with me, haven't written c++ in years) is identical assuming no expections are being thrown
Elaborated that for you. Sorry to be nitpicky but exceptions fans beg me to no end...
Quote:
Original post by davepermen
in this specific case, the std::auto_ptr would even work, but i normally tried to never touch it. it's like goto, something to better not use in general code (but in specific cases it can fit).
I don't understand your point. I think it's fine to use auto_ptr for scoped things like those. In general, everything that has ownership semantics will be fine with it as long as the semantics are respected. Lots of engineering details here.

Share this post


Link to post
Share on other sites
Quote:
Original post by davepermen
in the specific case talked about here, these two (bare with me, haven't written c++ in years) is identical:


int main()
{
GAME_ENGINE* engine = new GAME_ENGINE();
engine->run();
delete engine;
}


and


int main()
{
boost::smart_ptr<GAME_ENGINE> engine(new GAME_ENGINE())
engine-run();
}


Unfortunately, they are not identical. If engine->run() raises an exception, the the first snippet leaks (it would also not be clean .net in presence of Disposables). It would be near-identical if you would write e.g. the following:

int main()
{
GAME_ENGINE* engine = new GAME_ENGINE();
try {
engine->run();
} catch(...) {
}
delete engine;
}


[Edited by - phresnel on September 3, 2010 3:24:37 AM]

Share this post


Link to post
Share on other sites
to Krohm: thanks, indeed, exceptions. lets put a try catch all around the 2 or 3 lines of code, then it's identical?

why i don't like auto-ptr: because code grows. in this case, it won't. but in other cases, what could be a simple RAII like situation can suddenly evolve, put the ptr in some container, and let it alive much longer, in different places.

consider a resource loading function, where you store something temporarily only at first. at a later time, you put it into some cache-container. suddenly, the auto-ptr is dangerous.

to phresnel: indeed. bah, exceptions :)

well, if it would be idisposable in .net, i would have used using automatically.

thanks for showing the correct code.


public int Main(string[] Args)
{
using(var engine = new GAME_ENGINE())
{
engine->Run();
}
}

just for kicks :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
The only smart pointer defined in the C++ standard library (please do not say "STL"; that has not been a meaningful term for many years) is std::auto_ptr. You almost certainly do not want to be using std::auto_ptr for whatever it is you think you want to use it for. Its applicability is quite limited. In particular, you may not store them in a standard library container such as std::vector.


I thought you were being picky, but I see your point. Very specifically, I'm going to use tr1::shared_ptr<>, but, in my text, I was referring to smart pointers in general. I'm not intending to use auto_ptr. Actually, I thought that both shared_ptr & auto_ptr were only part of the tr1, not of the std alone.

Quote:
Original post by Zahlman
(please do not say "STL"; that has not been a meaningful term for many years)


I don't get it. could you please elaborate?


Share this post


Link to post
Share on other sites
[quote]Original post by davepermen
why i don't like auto-ptr: because code grows. in this case, it won't. but in other cases, what could be a simple RAII like situation can suddenly evolve, put the ptr in some container, and let it alive much longer, in different places.

[/code]

what is the differences then between std::tr1::shared_ptr & boost::smart_ptr? I'm deliberately excluding auto_ptr for reasons that I prefer to duel not. :D

Share this post


Link to post
Share on other sites
Quote:
Original post by draconar
Quote:
Original post by Zahlman
(please do not say "STL"; that has not been a meaningful term for many years)


I don't get it. could you please elaborate?


Back in the days, STL had been proposed by SGI to be included in the C++ standard library. Large portions of it are now part of the C++ standard library but not everything and there are also parts which are part of the standard which were not part of STL.
I frequently catch myself using the name as well even though I do not better, the name rolls very easily off the tongue. But one should at least be aware that using it is not correct in the general case.

Share this post


Link to post
Share on other sites
Quote:
Original post by draconar
what is the differences then between std::tr1::shared_ptr & boost::smart_ptr? I'm deliberately excluding auto_ptr for reasons that I prefer to duel not. :D

std::tr1 is the namespace for the next c++ standard (c++0x or something). it is the future default std:: namespace (or so).

so if you have that, use it's features (shared_ptr, that is).

boost is an independent group that proposes features for the c++ standards. they proposed shared_ptr years ago. tr1::shared_ptr is what came out of it.

so i suggest to use tr1 by now.

Share this post


Link to post
Share on other sites
Quote:
Original post by draconar
Quote:
Original post by davepermen
why i don't like auto-ptr: because code grows. in this case, it won't. but in other cases, what could be a simple RAII like situation can suddenly evolve, put the ptr in some container, and let it alive much longer, in different places.


what is the differences then between std::tr1::shared_ptr & boost::smart_ptr? I'm deliberately excluding auto_ptr for reasons that I prefer to duel not. :D


There is no boost::smart_ptr, but std::shared_ptr and std::tr1::shared_ptr and boost::shared_ptr are basically the same.


edit: should refresh more often :S

Share this post


Link to post
Share on other sites
Quote:
Original post by davepermen
in the specific case talked about here, these two (bare with me, haven't written c++ in years) are identical (except for exception savety, as pointed out below):


Plz do not say savety it is written SAFETY d00d!

Share this post


Link to post
Share on other sites
Quote:
Original post by howie_007
I think what you're really looking for is a singleton. I use them in my engine.


held by a smart pointer or such consideration is bogus?
Where would I new the singleton? in the Heap or stack?

Share this post


Link to post
Share on other sites
Quote:
Original post by draconar
Quote:
Original post by howie_007
I think what you're really looking for is a singleton. I use them in my engine.


held by a smart pointer or such consideration is bogus?
Where would I new the singleton? in the Heap or stack?


you're not looking for a singleton. that doesn't help you at all. which you can find out by searching on this page.

Share this post


Link to post
Share on other sites
Quote:
Original post by davepermen
i'll correct myself asap. to my excuse: i'm not native English, and i slept only 4h this night.. :) (and i didn't had spell correction turned on English. now i have). shame on me.


I was just goofing on the smart_ptr STL lgnisms earlier in the post, no offense intended.

[Edited by - mrchrismnh on September 3, 2010 10:16:03 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by BitMaster

Back in the days, STL had been proposed by SGI to be included in the C++ standard library. Large portions of it are now part of the C++ standard library but not everything and there are also parts which are part of the standard which were not part of STL.
I frequently catch myself using the name as well even though I do not better, the name rolls very easily off the tongue. But one should at least be aware that using it is not correct in the general case.


It's OK, Microsoft is wrong too. They keep using the term STL in their documentation. So does IBM. And Intel. And everyone else.

Personally, I'm happy if someone who lists 5+ years of in-depth C++ experience has:
- heard of STL
- used it
- really used it themselves (actually wrote some code)
- can actually list the basic few containers
- has programmed anything that was not C code compiled with C++ compiler

I have given up on trying to ask about:
- template programming (specialize a class)
- allocation techniques (how would you use a class that uses custom allocator)
- generic programming (algorithm.h, iterators, traits)
- boost (better left alone, the things people create with it are a disaster - they're better off using some other language)

So in practice, one ends up with something similar to Google's guidelines. C with classes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
It's OK, Microsoft is wrong too. They keep using the term STL in their documentation. So does IBM. And Intel. And everyone else.


this is it! I got even more confused because of these series on the STL by microsoft:

http://channel9.msdn.com/shows/Going+Deep/C9-Lectures-Introduction-to-STL-with-Stephan-T-Lavavej/


Quote:
Original post by Antheus
Personally, I'm happy if someone who lists 5+ years of in-depth C++ experience has:
- heard of STL
- used it
- really used it themselves (actually wrote some code)
- can actually list the basic few containers
- has programmed anything that was not C code compiled with C++ compiler

I have given up on trying to ask about:
- template programming (specialize a class)
- allocation techniques (how would you use a class that uses custom allocator)
- generic programming (algorithm.h, iterators, traits)
- boost (better left alone, the things people create with it are a disaster - they're better off using some other language)

So in practice, one ends up with something similar to Google's guidelines. C with classes.


Holy cow! so I'm doing so much better than I thought! With my years of using C++ as a hobbyist (well, at least hobbyist just a bit too obsessed...) I've dealt with most of the stuff you listed. The sad thing is that I'm most of time working alone and/or with ppl whose knowledge of the language is shallower than miner, so it gets difficult to advance.

But traits & template meta programming I still finding daunting and confusing for my level of expertise.

Will you hire me? *blink* *blink*

Share this post


Link to post
Share on other sites

This topic is 2655 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this