Starting out
Tutorials
C tutorial
C++ tutorial
Game programming
Graphics programming
Algorithms
More tutorials
Practice
Resources
Source code
C and C++ tips
Getting a compiler
Book recommendations
Forum
References
void myFunction()
{
myClass = new myClass();
// body of function
delete myClass;
}
and this may work. But what if somewhere in the function body an exception gets
thrown? Suddenly, the delete code never gets called! What's more, you may
never have intended to throw an exception into the function but one of the
functions you call may do so, or you may later need to modify your code to do
so. In both cases, this is a memory leak waiting to happen.
std::auto_ptr<int> int_memory_manager(new int); // Alternately, you could include "using namespace std;" or // "using namespace std::auto_ptr" at the top of your code to avoid having to // prefix all declarations with std::auto_ptrTo actually use the pointer stored in the auto_ptr container, you can just treat the auto_ptr object you create as though it were the pointer. For instance, you can dereference it:
*int_memory_manager = 5;and if you wanted to access a member function (or variable) of a struct or class, you can simply use the same arrow operator as normal. I'll use a fictitious class called "myClass" to illustrate this.
std::auto_ptr<myClass> myClassManager(new myClass); myClassManager->variable = 50;which sets a field called variable to 50 in the instance of myClass whose pointer is stored in myClassManager.
std::auto_ptr<int> int_memory_manager(new int[10]);What happens when int_memory_manager goes out of scope? The program invokes delete on an array, and this is illegal. Some compilers may let you get away with it, but it's not portable. Just don't do it! If you really need to store a collection of items with constant random access times, just use a vector from the Standard Template Library (STL).
int* example()
{
std::auto_ptr<int> int_memory_manager(new int);
return int_memory_manager.release(); // we'll see release in more depth below
Of course, you'd probably be better off simply returning an auto_ptr object in
the first place.
std::auto_ptr<int> int_memory_manager(new int); std::auto_ptr<int> int_memory_manager2; cout<<"Contents of first is "<<int_memory_manager.get()<<endl; int_memory_manager2 = int_memory_manager; cout<<"Contents of first is "<<int_memory_manager.get()<<endl; cout<<"Contents of second is "<<int_memory_manager2.get()<<endl;This sample program demonstrates that the overloaded copy operator for auto_ptr actually removes the pointer from the object being copied! It's set to NULL. This means that only one auto_ptr object can hold a pointer at any time. The act of assigning one auto_ptr to another changes the auto_ptr being assigned. Moreover, this situation holds true even when implicitly copying auto_ptr objects -- for instance, if you make a function call and pass an auto_ptr object, when the function returns, the contents of auto_ptr will be changed to NULL, as demonstrated by the following code:
using namespace std;
void aFunction(std::auto_ptr<int> x)
{
}
int main()
{
std::auto_ptr<int> int_manager(new int);
aFunction(int_manager);
cout<<"Content of int_manager is "int_manager.get()<<endl;
// Expected output: 0
}
In truth, this behavior is quite beneficial because it means that two auto_ptr
objects will not both try to delete the same pointer. Deleting the same
pointer twice is not a valid operation, and can lead to program crashes,
whereas deleting NULL is a valid operation (though it doesn't change anything).
std::auto_ptr<int> int_memory_manager(new int); // Calling release sets the pointer managed by int_memory_manager to point // to NULL int *need_to_delete_ptr = int_memory_manager.release(); delete need_to_delete_ptr;Finally, if you happen to want to reuse an auto_ptr object, you can simply call the reset function to free the old memory and set the new memory:
std::auto_ptr<int> int_memory_manager(new int); int_memory_manager.reset(new int);Using auto_ptr won't solve all of your problems. First, you could still write code that manually handles pointers that are also managed by auto_ptr objects. Doing this could result in double deletes. Whenever you request manual control of a pointer from an auto_ptr, you open yourself up to the requirement to call delete on that pointer -- consequently, the possibility of a memory leak exists.