This article is a part of Understand C++ Memory Allocation.
Use of raw pointers
Avoid using raw pointers. Use one of auto_ptr, scoped_ptr, shared_ptr or weak_ptr, as appropriate.
Use auto_ptr where appropriate.
Where okay to use:
- On the stack
- As a return value of a function
- As a parameter that passes ownership to another function
- As a data member in a non-copyable class.
Where not okay to use:
- For C arrays.
- In STL containers.
- As a data member in a copyable class with no special support for in the copy constructor or assignment operator.
Standard use: BEFORE:
Config* settings = new Config(); .... delete settings;
auto_ptr <Config> settings( new Config() );
scoped_ptr and scoped_array
(This is available in Boost, in ClassUtilities, or it may be available in newest versions of C++)
If available, scoped_ptr can be used instead of auto_ptr for stack objects, and only stack objects.
scoped_array can be used for dynamically allocated arrays on the stack.
Neither scoped_ptr or scoped_array can be used in stl containers.
Available in Boost or may be available in newer versions of C++.
shared_ptr uses reference counting to implement a simple garbage collector. In most cases, shared_ptr can be used whenever a pointer is used. The exception has to do with the typical problem with referenced counted objects, which is that it is possible to have a circular reference (i.e. A references B, which referneces A. Neither gets referenced counted down to 0, so they stay in memory. The solution is to break the circular reference in one of the directions by using a raw or weak_ptr.)
shared_ptr is becoming the defacto-standard for C++ pointers, as suggested by many in the C++ community. It is part of the latest C++ TR and will be part of the standard C++0X Standard.
Prefer stack objects
When using the C++ “new” operator, consider how the object is going to get deleted if an exception is thrown. In most cases, when creating the object on the stack, you can simply create the object as an auto stack variable. Example:
LPSYSTEMINFO lpsi = new SYSTEMINFO; GetSystemInfo( lpsi ); delete lpsi;
SYSTEMINFO si; GetSystemInfo( &si );
The first version is miscoded. It is common in code written by programmers new to Windows. It’s important to remember that types such as LPxxxx means xxxx*. Simply because the GetSystemInfo API takes a parameter of type LPSYSTEMINFO does not mean that that is the exact type that needs to be passed in – passing in a reference to SYSTEMINFO is preferred to avoid the heap allocation.
However, if “new” needs to be used to create a local object, consider using auto_ptr so that it gets deleted automatically.