Probably all that I'm asking for is a link to a website that I have yet to find. But coming from a Java background, what are the general guidelines for handling memory allocation and deletion in C++? I feel like I may be adding all sorts of memory leaks to my application. I realize that there are several variants of smart pointers, and you can mention them too me as well, but I'd like to focus on standard C++ pointers.
-
4Well, the usual guidelines favour smart pointers or other alternatives over raw pointers. – Georg Fritzsche Jul 20 '10 at 12:12
-
pun intended: "pointer" tag :D – rubenvb Jul 20 '10 at 12:20
-
1Whatever solution and policy you choose, it will not be perfect and you will make mistakes. That is why God, in his infinite wisdom, created Valgrind (http://valgrind.org/). – Amir Rachum Jul 20 '10 at 12:51
-
@Amir: I would say that there are certain design principles that help minimize the probability of errors a great deal -- even and especially in C++. – sellibitze Jul 20 '10 at 18:42
-
1@Amir: it wasn't God, it was Julian Seward, and in his spare time he created `bzip2`. http://en.wikipedia.org/wiki/Julian_Seward – Matthieu M. Sep 10 '10 at 06:46
9 Answers
My usual policy is this
- Use smart pointers where usage is at all complex.
- All raw pointers are owned by a specific object that is responsible for deleting it.
- The constructor always either allocates the pointer or initializes it to null if it's to be set later.
- The destructor always deletes any contained pointers
- Those rules ensure that pointers get deleted when their owning objects are deleted eliminating most common memory leak situations.
- Never pass an internal pointer into another object, always pass the container object and have the the called function call member functions of the container object to act on the "pointer".
- Disable copying of the container object. In rare cases implement the copy so that it copies the pointed to object. But never allow the owning object to be copied without also copying the contained object.
- The previous two rules ensure that you can't have copies of the pointer pointing to deleted memory.
- Don't try to implement reference counting. If you need a reference counted pointer use a smart pointer class and contain that.
I've found those rules generally ensure you can use raw pointers safely and efficiently, and if you want to break those rules then use a smart pointer instead.

- 29,554
- 19
- 87
- 130
-
2Sometimes, you don't need to do anything special with pointers as members. Think of iterators. So, it really depends on what semantics you are going for. Deleting objects in the iterators' destructors is a bad idea. ;-) – sellibitze Jul 20 '10 at 12:44
-
There are always exceptions to a rule :) I would argue that even in this case you are taking a calculated risk though. If your object stores a pointer to an object then that object can be deleted without it's knowledge which is a bad thing. That risk is probably acceptable for a common idiom like an iterator that has usage patterns that don't lead to a huge risk of misuse. But for a general case I would suggest that you need to think twice about storing a raw pointer to an object you don't control the lifetime of. – jcoder Jul 20 '10 at 13:13
-
Not suggesting that you don't do it, sometimes it's necessary... But when I do it, it's a deliberate choice to break my policy and a good indicator that there maybe lifetime issues with that object. – jcoder Jul 20 '10 at 13:15
Usually, we use new
to allocate memory, and delete
to free it. (Mainly because new
calls the appropriate constructors, and delete
the appropriate destructors).
But most of people here will advise you against using raw pointers other than for educational purposes (well except when the overhead of smart pointers is significant, like in embedded programming).
Knowing of things work is important, but in most cases, you can take advantage of well designed smart pointers classes to make things easier for you (and often safer).
Smart pointers exist for a reason: to help programmers do great programs without having to care too much about handling allocation/deallocation.

- 53,676
- 39
- 161
- 238
-
3@C Johnson: Glad I made you laugh :) Care to elaborate what you think is that funny ?! :) – ereOn Jul 20 '10 at 12:16
-
ereOn; smart pointers or not, you might want to add a note regarding custom allocators and memory pools. – falstro Jul 20 '10 at 12:20
-
Hey, you edited out the educational part? You should put it back in. :) Edit: Oh I see it is there now. Cool! – C.J. Jul 20 '10 at 12:21
-
@C Johnson: I never edited it out. Perhaps you should buy glasses... and a book about smart pointers :) Or just tell us clearly why you seem to disagree. I don't bite, I swear. – ereOn Jul 20 '10 at 12:30
Use pointers with extreme paranoia. For every member variable that you declare in a class, document whether it owns the memory lifetime of the memory it points to. If it does, then it's responsible for allocating and freeing the memory. And if it does own the memory it points to, document it CLEARLY! Also remember, allocate in the constructor and deallocate in the destructor. It's a great rule, that you ignore at your peril. Also NULL out your pointers except when you are using them. NULL them when they are initialized, and after you free them. Put lots of asserts everywhere checking the integrity of your pointers BEFORE you dereference them. Put in real guards to handle situations when they are bad.
Last and most important of all:
FIRE any bozo in your company who abuses these policies!!! They are literally injecting untold damage into your product, and causing lots of bugs and headaches down the road.

- 15,637
- 9
- 61
- 77
-
Or you can use smart pointers when the overhead is acceptable, to avoid having to explicitly set to `NULL` :) – ereOn Jul 20 '10 at 12:28
-
We are starting to use smart pointers more nowadays. But we still have 99,567 more to go! ;) – C.J. Jul 20 '10 at 12:30
I also came from Java and it took a while to learn how good design looks like in C++. At first, it's hard to think about who's responsibility it is to delete things. The answer is to defer these responsibilities to objects, to let objects own/manage other objects or resources and let them worry about deletion/release or copying. C++ makes this easy via constructors, destructors, etc. They keyword is "RAII" (resource acquisition is initialization).
Often, I manage to organize the "x owns y"-relationship as a forest where the tree's roots all live on the stack (automatic memory). By using standard containers and avoiding pointers as data members I reduce the number of new/delete calls in my code to a minimum (almost none). This is the simplest thing to work with. Sometimes, you may feel the need to use shared-ownership smart pointers, but in my experience, people tend to overuse those. But they are, of course, useful in some cases.

- 27,611
- 3
- 75
- 95
If you really do need to handle raw pointers, then I suggest wrapping them with smart pointers if possible. If you will be storing them in an STL container, you'll need to use a tr1::shared_ptr
instead of an auto_ptr
.
While you're learning I would suggest steering clear of pointers whenever you can, to avoid headaches. For example, if you want an array of int
s, you can use a vector
rather than allocating and freeing the memory yourself. If you want to instantiate a class, do it in automatic memory, i.e.
MyClass myObject;
instead of
MyClass *myObject = new MyClass();
// ...
delete myObject;
-
`shared_ptr<>` is not always required. Sometimes a `scoped_ptr<>` is enough and has a less overhead. – ereOn Jul 20 '10 at 12:39
-
-
@ereOn: I always thought that STL containers always required their contained objects to be copyable. Thanks for the heads-up. – Jul 20 '10 at 12:47
-
Sorry, my comment was unclear. I wasn't explicitely talking about containers, but about pointers in general. My mistake. I believe STL containers indeed require the contained objects to be copiable. However, note that `boost` also provides specific containers, similar to the STL ones, but that are easier to use with smart pointers. – ereOn Jul 20 '10 at 13:00
I use following policy:
Never use raw pointers that own objects.
Foo *f=new Foo(); // Bad!
Even in Classes :
class Bar { Bar(Bar const &); // non copyable void operator=(Bar const &); public: Bar() { f1_=new Foo(); f2_=new Foo(); // this throws then f1_ never destroyed! } ~Bar() { delete f1_; delete f2_ ;} Foo *f1_,*f2_; }; // Bad code
Correct:
class Bar { Bar(Bar const &); // non copyable void operator=(Bar const &); public: Bar() { f1_.reset(new Foo()) f2_.reset(new Foo()); } std::auto_ptr<Foo> f1_,f2_; }; // Good code
For object without shared ownership use
auto_ptr
std::auto_ptr<Foo> f(new Foo()); // Good
For shared ownership or containers, use
boost::shared_ptr
orstd::tr1::shared_ptr
std::vector<boost::shared_ptr<Foo> > foos;
When I need to transfer ownership on object to some other object, use
auto_ptr
void assign_foo(std::auto_ptr<Foo> f) { /// I own foo } std::auto_ptr<Foo> transfer_foo(std::auto_ptr<Foo> f) { ... } // Now foo is owned by caller
So it is clear who gives whom a pointer.
Raw pointers are allowed only as references that can be null and they never own objects
void bar1(Foo *f) { do something with f if f!=NULL}

- 31,019
- 21
- 127
- 215
Have you thought of using a garbage collector. This Garbage Collector is currently used by the Mono project, although I understand it's getting replaced with a more aggressive version. It may help, as its will provide a similar experience when developing in C/C++ as when you developed on Java.

- 4,213
- 11
- 35
- 64
As others have said you need read up on RAII. I found this useful when I was learning C++, its old but gives the basic ideas.

- 428
- 1
- 5
- 10