So the essence of my problem is this:
//Big.h
class Big{
public:
int a, b;
};
//Mini.h
class Big;
class Mini{
public:
Mini(float a, shared_ptr<Big> ptb):ma(a), me(-a), ptb(ptb){};
float ma, me;
shared_ptr<Big> ptb;
};
//main
int main(){
std::list<Mini> lm;
if(true){ //Or some sub function or rutin
Big big; big.a = 100; big.b = 200;
Mini derp(5, shared_ptr<Big>(&big));
lm.push_front(derp);
}
//Do something
};
Compiles fine but it gives a "double free or corruption" when exiting main (in the full program this is just a sub function)
I suspect the shared_ptr
to big
is being freed at some point and then again when exiting main, but I'm not sure and have no idea of how to fix it. Can someone please explain to me the reason of this error?
I red that I had to NULL
the pointer to but I don't know where.
Or maybe I'm just using the wrong smart pointer or something like that?
Thanks
Double Free A simple technique to avoid this type of vulnerability is to always assign NULL to a pointer after it has been freed. Subsequent attempts to free a null pointer will be ignored by most heap managers.
In C++, a shared pointer is one of the smart pointers. The shared pointer maintains a reference count which is incremented when another shared pointer points to the same object. So, when the reference count is equal to zero (i.e., no pointer points to this object), the object is destroyed.
The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.
By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).
You're constructing a shared_ptr
with a pointer to an existing object on the stack. Don't do that; that's not how shared_ptr
is meant to be used. Ordinary stack objects should never be deleted or freed. The object it's pointing at is supposed to be on the heap, i.e. created using new
or the equivalent.
The recommended way to create a shared_ptr
is through make_shared
:
auto p = make_shared<Big>();
or the old-fashioned way:
shared_ptr<Big> p(new Big);
Objects managed by a shared_ptr
must be constructed in dynamic scope, i.e. allocated with new
.
Big big;
big.a = 100;
big.b = 200;
Mini derp(5, shared_ptr<Big>(&big));
And here, you're shoving a pointer to an object that was constructed in automatic scope into a shared_ptr
. shared_ptr
now thinks it owns this object, and it gets to decide when it is going to delete
it.
But when this object in automatic scope goes out of scope and gets destroyed, this will make this shared_ptr
very, very sad.
Use new
to construct this object, instead of constructing it in automatic scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With