Sign in to follow this  
_Sigma

boost variant and memory allocation

Recommended Posts

What is the proper way of dealing with this situation:
boost::variant<int*, myType42> foo;
foo = new int;
delete ...?

That is, what is the proper way of deleting allocated memory held by a variant?

Share this post


Link to post
Share on other sites
using direct type check and casting would be something like this.

foo = new int( 123);

if( foo.type() == typeid( int *)) {
int *p = boost::get< int *>( foo);
delete p;
}

Share this post


Link to post
Share on other sites
It occurred to me that if all the types that you wish to represent are pod types (pointers int/float etc) and if you handle memory externally, then it might be easier to just use a c-style tagged union. The advantage of boost variant is that it respects constructors/destructors so you can employ normal c++ raii techniques and use it to hold things like std::string or shared_ptr<>. If this is not required or desirable, then a c-style union and an enum will probably achieve the same effect, and with a similar a amount of keyboard jockeying. unions are one the really nice things about c that got lost in c++.

Share this post


Link to post
Share on other sites
Quote:
Original post by _Sigma
What is the proper way of dealing with this situation:
*** Source Snippet Removed ***
That is, what is the proper way of deleting allocated memory held by a variant?


The correct way of deleting pretty much *any* allocated memory is to get someone else to do it for you.


variant<shared_ptr<int>, myType42>

Share this post


Link to post
Share on other sites
There should NEVER be a delete outside of the destructor of an object that owns a resource.

Learn the basics of C++ programming, particularly RAII and ownership, which are the most important things. Exception-safety is important too (and RAII guarantees the basic guarantee is met).

Share this post


Link to post
Share on other sites
Quote:

Perhaps you could use a smart pointer instead of a raw pointer, though.
[...]
The correct way of deleting pretty much *any* allocated memory is to get someone else to do it for you.
variant<shared_ptr<int>, myType42>

Thanks. I was going to go this route, but it does involve some code-rewrite, so I just wanted to make sure I wasn't missing something.

Quote:

It occurred to me that if all the types that you wish to represent are pod types (pointers int/float etc) and if you handle memory externally, then it might be easier to just use a c-style tagged union. The advantage of boost variant is that it respects constructors/destructors so you can employ normal c++ raii techniques and use it to hold things like std::string or shared_ptr<>. If this is not required or desirable, then a c-style union and an enum will probably achieve the same effect, and with a similar a amount of keyboard jockeying. unions are one the really nice things about c that got lost in c++.

Sorry, I actually need classes to be held, such as std::string, etc. Thus variant as opposed to a union. I just used int as an example because I was typing this without my contacts in and it was quicker to type int. Sorry!

Share this post


Link to post
Share on other sites
Quote:
Original post by _Sigma
What is the proper way of dealing with this situation:
*** Source Snippet Removed ***
That is, what is the proper way of deleting allocated memory held by a variant?
Although I've never tried it myself, I would assume you would access and/or modify a raw pointer held by a variant in the same way you'd access any other type: via get() or apply_visitor().

Since you're using variant I'm guessing you're already familiar with both of these access methods, but in any case, here's an example using get() (not compiled or tested):

boost::variant<int*, myType42> foo;
foo = new int;
delete foo.get<int*>();

I'd probably use apply_visitor() myself, but that would have made for a longer example :)

As mentioned previously though, it would probably be better to use an RAII container that can clean up its own resources.

Share this post


Link to post
Share on other sites

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