boost::shared_array - deleting contents

Started by
13 comments, last by MaulingMonkey 15 years, 8 months ago
I'm using boost::shared_array to hold an array of float*. However, I need to be able to potentially delete all this memory before the smart pointer goes out of scope. I will be replacing said array with a new one of (probably) different size. Is it safe to do this:

boost::shared_array<float> ptr(new float[500]);
delete[] prt.get();




Cheers.
Advertisement
Unfortunately that isn't possible (based on what you've described). Why don't you share an object that can resize such as boost::shared_ptr<std::vector<float> > ?
I really don't need any of the vector overhead...So I would rather not go down that path.

Quote:Unfortunately that isn't possible

The code I posted compiles and *seems* to run. What makes it not possible?
Quote:(based on what you've described)

What would I have to describe to make this possible?

Ultimately I need this:
boost::shared_array<float> ptr;// stuffptr = boost::shared_array<float>(new float[row*col]);//stuffdelete[] ptr.get();//stuffptr = boost::shared_array<float>(new float[new_row*new_col]);

I would like to have a smart pointer here (I'm looking for exception safety) - any recommendations so I can do the above?
You never want to invoke delete on the return value of get(). (Well, I suppose there are no 'nevers' in C++, but you know what I mean.)

With boost::shared_ptr, you would (I think) use the reset() function for this:
boost::shared_ptr<Foo> foo_p(new Foo);foo_p.reset(new Foo); // The previously allocated 'Foo' is deletedfoo_p.reset(); // The previously allocated 'Foo' is deleted (and the shared pointer is now 'empty')
I assume shared_array works in a similar fashion (although I've never used it myself).
Quote:Original post by jyk
You never want to invoke delete on the return value of get(). (Well, I suppose there are no 'nevers' in C++, but you know what I mean.)

With boost::shared_ptr, you would (I think) use the reset() function for this:
boost::shared_ptr<Foo> foo_p(new Foo);foo_p.reset(new Foo); // The previously allocated 'Foo' is deletedfoo_p.reset(); // The previously allocated 'Foo' is deleted (and the shared pointer is now 'empty')
I assume shared_array works in a similar fashion (although I've never used it myself).


As long as he only wants exception safety and he doesn't intend for there to be any other smart pointers referencing that array, then that'll do it.

  • If you use shared pointer semantics, then you can't reliably destroy the shared object. This is because the object may be referenced by other pointers and must therefore be kept alive. What you can do is stop referencing the shared object and start referencing a new one. If nobody else references the old object, it will be destroyed.

  • The overhead of std::vector is smaller than the overhead of boost::shared_array, because there is no sharing involved. So, if you don't need sharing and instead just need control over a buffer of memory in an exception-safe way, using a vector is both semantically correct and more efficient.
Quote:Original post by _Sigma
The code I posted compiles and *seems* to run.

It will delete the buffer again when it hits the end of ptr's scope, invoking undefined behavior. In practice, it will definitely explode if your allocator tries to reuse that memory before the last shared_array instances goes out of scope. You can however release your claim early with ptr.reset(), which will invoke delete if it was the last shared_array instance owning that buffer.

Given that you've stated "replace", however, I'm guessing you almost certainly want boost::shared_ptr<std::vector<float> > here, assuming you actually need shared semantics, because that replacement won't be reflected in the other shared_array instances otherwise / as currently stands -- you share changes to the array, but you won't share changes to which array is being used with your current code. Of course, this is assuming you even need sharing semantics. If you don't, why the **** aren't you just using std::vector? 0_o.
Quote:Original post by _Sigma
I really don't need any of the vector overhead...So I would rather not go down that path.


What overhead? You've got to pay the memory allocation cost, no matter if you do it yourself via new[] or let the allocator do it. And if the vector doesn't grow beyond its .capacity(), there's no overhead compared to raw arrays.
Alright, I appreciate all the feedback. I assumed that calling delete[] was bad but I'm happy to know why.

Must admit my knowledge of STL isn't the strongest - can anyone explain why using a vector is going to give me exception safety with pointers?

I need thread safety and my current understanding is that STL does not guarantee this. I don't need to grow/shrink the vector after is is created; just need it to be safe to have multiple threads access and change items (different items).



Quote:Original post by _Sigma
Must admit my knowledge of STL isn't the strongest - can anyone explain why using a vector is going to give me exception safety with pointers?
With pointers? The reason why people use the SC++L containers (and vectors in particular) is that they don't need to use pointers to reference dynamic sequences of data.

The SC++L containers are designed to be exception-safe: no matter when an exception is thrown, the container will remain in a valid state and, if an exception happens to leave the scope the container is defined it, the container's data will be cleared correctly. In short, there's no way you can use an exception to waste a container or lose its internal memory.

Of course, if you store pointers inside a container, then you have to take care of those pointers yourself.

Quote:I need thread safety and my current understanding is that STL does not guarantee this.
This is an entirely different kind of thing, and neither SC++L containers nor boost shared array pointers offer thread-safety. If you think you will be accessing the same data from two threads, you need a lock (possibly using boost's mutex library).

This topic is closed to new replies.

Advertisement