Reputation: 6029
In practicing with smart pointers and seeing how they can prevent memory leaks and aid memory management through RAII, I was doing the following:
#include <boost/shared_ptr.hpp>
#include <vector>
#include <iostream>
using std::cout;
using boost::shared_ptr;
class myobj {
public:
shared_ptr<int> a;
myobj() {
shared_ptr<int> b(new int[50]);
a = b;
}
~myobj() {}
};
typedef boost::shared_ptr<myobj> myobj_ptr;
int main() {
for (unsigned int i=0; i < 5000000; i++) {
myobj *foo = new myobj();
myobj *bar = new myobj();
myobj_ptr bar_ptr(bar);
bar_ptr = myobj_ptr(foo);
bar = foo;
}
return 0;
}
Is there any way I could something similar to this (hopefully my aim comes across in the 'pseudo' code):
a = new int[50];
I can see why this won't work from the Boost shared_ptr.hpp file itself, but I don't understand why this will not work then:
shared_ptr<int> a;
int *b;
myobj() {
b = new int[50];
boost::detail::sp_enable_shared_from_this( a, b, b );
}
It returned this error:
warning: cannot pass objects of non-POD type ‘class boost::shared_ptr<int>’ through ‘...’; call will abort at runtime
Which I don't exactly understand.
Upvotes: 0
Views: 890
Reputation: 231343
First, anything in boost::detail
is an implementation detail. Don't touch it unless you're developing code that will be a part of boost itself.
Second, boost::shared_ptr
is not directly capable of wrapping arrays. This is because arrays in C++ must be deleted with delete []
, while boost::shared_ptr
deletes with delete
instead. Use boost::shared_array
instead, or perhaps a boost::shared_ptr
to a std::vector
. If you really must use a shared_ptr
with an array, you must create it using a custom deleter:
template <typename T>
struct array_deleter {
void operator()(T *p) {
delete [] p;
}
};
// later...
boost::shared_ptr<int> p(new int[50], array_deleter<int>());
Please don't actually do this, however. Use a shared_array<int>
or a shared_ptr<vector<int> >
.
As for why you can't just do:
boost::shared_ptr<int> a;
// later
a = new int;
This is because it would be dangerous to make it too easy to make something a shared_ptr - remember, if you make something a shared_ptr twice, you'll end up double-freeing it. So shared_ptrs will only take raw pointers through their constructor. If you really want to overwrite a shared_ptr with a raw pointer, here's one way:
a.swap(boost::shared_ptr<int>(new int));
This creates a new pointer, then swaps it with a
. The temporary smart pointer (with a
's old value) is then freed.
Upvotes: 3
Reputation: 373042
For starters, the function you're calling is in the detail
namespace, meaning that it's probably not meant to be invoked directly. That may have something to do with your problem.
As for the particular error you're getting, that error usually means that you tried to call a varargs function passing in a non-POD argument. In this case, that's because boost::shared_ptr<int>
isn't a POD type. I think this has nothing to do with using arrays versus raw pointers; I think you're just calling the wrong function with the wrong arguments. Did you mean to use boost::shared_from_this
?
Upvotes: 0
Reputation: 792767
You can't assign something allocated with new int[50]
to a shared_ptr<int>
unless you also supply a custom deleter that performs delete[]
instead of delete
.
enable_shared_from_this
is designed to add the ability for class types to retrieve an owning shared pointer, you've just pulled something out of the detail
namespace. This isn't designed to be used directly. It's designed to be used like this.
class myobj : public boost::enable_shared_from_this<myobj>
{ //...
The simplest managing container for arrays would be std::vector<int>
, not shared_ptr
.
Upvotes: 2