Multiple deletion of C ++ memory pointed to by several objects

Another issue of removing a pointer to C ++ is given in the following example:

class Foo { public: int *p; ~Foo() { delete p; p = NULL; } }; Foo *f1 = new Foo(); Foo *f2 = new Foo(); f1->p = new int(1); f2->p = f1->p; delete f2; // ok delete f1; // no error? 

Why didnโ€™t I get an error when calling "delete f1"? Did I delete the same address (* p) twice?

If I immediately remove the pointers in the last two lines of code, I get an error.

 delete f2->p; // ok delete f1->p; // error!! *** glibc detected *** double free or corruption (fasttop) *** 
+4
source share
5 answers

This is very bad. However, C ++ will not necessarily do something here. This is "indefinite" behavior. This does not mean that it will crash, but it is likely to cause bad shit (tm).

Edit: Also, in the second example, the fact that it crashes is only part of the "undefined" behavior. undefined regarding the reaction.

+5
source

Believe me, you do not want to do this.

Take a look at boost::shared_ptr : it allows you to deal with pointers in an elegant way without worrying too much about deleting them.

 class Foo { public: boost::shared_ptr<int> p; }; Foo *f1 = new Foo(); Foo *f2 = new Foo(); f1->p.reset(new int(1)); f2->p = f1->p; delete f2; // ok delete f1; // no error and its guaranteed ! 

If you do not want to use boost , some compilers already provide std::tr1::shared_ptr , which has similar semantics.

+3
source

Why didnโ€™t I get an error when calling "delete f1"? Did I delete the same address (* p) twice?

Yes, you deleted this item twice.

However, the result of this is Undefined Behavior . This can cause the runtime system to catch the error and pull out a message, but it can cause your HD to be formatted, nasty nasal demons chasing you all over the office to the delight of your colleagues or you or your girlfriend will get pregnant. Or then it may seem โ€œworking,โ€ no matter what it means in this case.

+3
source

If you want to use multiple pointers in the same memory, encapsulate them in boost::shared_ptr , which ensures that the base memory will not delete -d until the last reference to it leaves the scope.

 #include <boost/shared_ptr.hpp> class Foo { public: boost::shared_ptr<int> p; ~Foo() { p.reset(); } }; Foo *f1 = new Foo(); Foo *f2 = new Foo(); f1->p.reset(new int(1)); f2->p = f1->p; delete f2; // ok delete f1; // no error 
+1
source

Of course, double deletions are undefined behavior. It is also likely to change if between debug and release builds. Others have indicated the kindness of boost::shared_ptr , etc.

However, it is also useful to mention how you can reliably find these errors:

Run your program in valgrind .

On Windows, purify is an older commercial partner valgrind.

0
source

All Articles