Hi this is my first post in a series of posts on memory management in C++.
Why smart pointers?
Suppose we have a code like
void someMethod();
void someOtherMehtod();
a->someMethod();
template<typename T> class auto_ptr {
public:
explicit auto_ptr(T* t = 0)
: m_ptr(t)
{
}
virtual ~auto_ptr()
{
delete m_ptr;
}
T& operator*()
{
return *m_ptr;
}
T* operator->()
{
return m_ptr;
}
T* get() const
{
return m_ptr;
}
T* m_ptr;
};
As you can see "auto_ptr" is just a wrapper around a raw pointer. It guaranties object deletion when it goes out of scope.
Now in order to use "auto_ptr", our implementation of "foo()" will look like
void foo()
{
auto_ptr<A> a(new A());
a->someMethod();
}
Or we can use auto_ptr provided by C++ standard library
void foo()
{
std::auto_ptr<A> a(new A());
a->someMethod();
}
As you can see their is no need for "delete" here, auto_ptr guarantees us it will call "delete" operator no matter what happens inside fooBar().
Another advantage is we can still use dereference operator with smart pointers just like with raw pointer. Because it has overloaded "*" and "->" operators inside "auto_ptr" class.
"auto_ptr" is the most simplest kind of smart pointers. Their are many more available, which have their own memory management policy.
Why to use smart pointers?
It makes our code less buggy.
void foo()
{
A* a1 = new A();
A* a2 = a1;
a1->someMethod();
delete a1;
It is safe to use, it automatically initialises its instance member through default constructor.
It make our code partially garbage collected, we no more need to call delete, it does this for us :)
I will talk about more on smart pointers with introduction to some other kinds available.
Why smart pointers?
Suppose we have a code like
class A {
public:
A();
void someOtherMehtod();
// .....
};
void fooBar(A* a);
void foo()
{
A* a = new A();
// do something with a
fooBar(a);
delete a;
}
This is a simple a straight forward code, we are creating an instance of "A", passing "a" as an argument to "foo" function and then deleting it. Pretty nice until now :)
But their is a potential memory leak here. In order to release memory obtained through "new" operator we must use "delete" operator, otherwise memory will leak. Suppose if we do not remember to call "delete" or suppose inside "fooBar()" implementation an exception occurs, then control will never return back and "delete a;" is never executed and we will be leaking memory :(
Same is true when you use any third party API, it can also raise an exception. Remember we are only sure about our own code, we cannot guarantee any one else code.
The simple solution is to use "auto_ptr"(a smart pointer) provided by C++ standard library.
A simple "auto_ptr" class might look like
template<typename T> class auto_ptr {
public:
explicit auto_ptr(T* t = 0)
: m_ptr(t)
{
}
virtual ~auto_ptr()
{
delete m_ptr;
}
T& operator*()
{
return *m_ptr;
}
T* operator->()
{
return m_ptr;
}
T* get() const
{
return m_ptr;
}
// some other methods
private:T* m_ptr;
};
Now in order to use "auto_ptr", our implementation of "foo()" will look like
{
auto_ptr<A> a(new A());
a->someMethod();
// do something with a
fooBar(a.get());}
Or we can use auto_ptr provided by C++ standard library
void foo()
{
std::auto_ptr<A> a(new A());
a->someMethod();
// do something with a
fooBar(a.get());}
As you can see their is no need for "delete" here, auto_ptr guarantees us it will call "delete" operator no matter what happens inside fooBar().
Another advantage is we can still use dereference operator with smart pointers just like with raw pointer. Because it has overloaded "*" and "->" operators inside "auto_ptr" class.
"auto_ptr" is the most simplest kind of smart pointers. Their are many more available, which have their own memory management policy.
Why to use smart pointers?
It makes our code less buggy.
void foo()
{
A* a1 = new A();
A* a2 = a1;
a1->someMethod();
delete a1;
a1->someOtherMehtod(); // Ohhh a1 is dangling, and we will get a crash here
a1 = NULL; // a1 is now no more dangling
a2->someOtherMehtod(); // a1 is still dangling here
}It is safe to use, it automatically initialises its instance member through default constructor.
It make our code partially garbage collected, we no more need to call delete, it does this for us :)
I will talk about more on smart pointers with introduction to some other kinds available.
No comments:
Post a Comment