Monday, April 28, 2014

auto_ptr

Introduction

Pointer Misuse is a major bug in c++.Its misuse mostly led to memory leaks that means you have done some dynamic allocation of memory but somehow failed to deallocate it. These memory leak become more important in languages like c and c++ where automatic garbage collection is not there.

A simple code snippet given below will tell u about this problem
void testfunc()
{
   int *ptr = new int[10];
}
int main()
{
   testfunc();  
}
This test function(testfunc()) allocates memory of 10 integers to ptr and even when this function testfunc() goes out of scope memory is not freed so it creates memory leak and to handle all this kind of problem concept of smart pointers is introduced.so what actually is this smart pointer

Smart pointer is like a normal pointer but with a capability that it destroys its contents automatically when it goes out of scope.



Now in c++ various implementation of smart pointers exist, i will discuss auto_ptr first.

auto_ptr

This is deprecated in c++11 but let's see what actually was its disadvantages that led to its deprecation 

auto_ptr is a template class that has mechanism of garbage collection.This means when auto_ptr goes out of scope it deallocates the contents of pointer it is holding.

following code snippet will clear this thing

void mytemp()
{
    int *ptr = new int(3);
    auto_ptr<int> intmanager(ptr);
    
}
So when this function terminates and auto_ptr intmanager goes out of scope then memory allocated by ptr will automatically be deallocated by auto_ptr by calling delete on it. point to be noted here is that 
auto_ptr deallocate memory using delete. so it doesnot free memory allocated by malloc,calloc and realloc and one cannot use arrays with auto_ptr even though it is not compilation error but delete
instead of delete[] on arrays will led to memory leaks.

one can use auto_ptr with classes as well for e.g. if you a class testclass then you can declare auto_ptr to that as follows :

auto_ptr<testclass> ob(new testclass)
After that you can use it as a normal pointer way
ob->myvariable;

The main issue with auto pointer is that it has semantics of strict ownership meaning that one auto_ptr is responsible for complete lifecycle of object it contains and when one auto_ptr is copied into another first one loses its reference.It will become clear with following code snipppet

char *ptr = new char;
auto_ptr<char> chM1(ptr);
auto_ptr<char> chM2;
chM2 = chM1;        // transfer of ownership occurs
cout<<"Address 1 : "<<chM1.get() ; // get() function will return address so it is null now as transfer of                                                                   // ownership already occured
cout<<"Address 2 : "<<chM2.get());   // this will print address

Because of this copy semantics auto_ptr cannot be used with many STL containers like we cannot have vector of auto_ptr's.code snippet given below will explain this

auto_ptr<int> temp(new int);
vector<auto_ptr<int> > tempvec; //till this point no error 
tempvec.push_back(temp); //this will give error

auto_ptr has a copy constructor with a non-const parameter, so the compiler can't call it from vector::push_back() since the latter has const parameter.

How to reset and release auto_ptr ?

one can reset auto_ptr by using reset() function which will call destructor,frees memory associated with previous pointer object and then associate new pointer object with it . following code will demonstrate that

int *ptr1 = new int;
int *ptr2 = new int;
auto_ptr<int> ptra(ptr1);
ptra.reset(ptr2); 

When one release auto_ptr then function will reset auto_ptr internal pointer to null without destructing the object currently pointed by auto_ptr so now the onus lies on programmer to deallocate the memory.

int *ptr3 = ptra.release();