Naija Ryders

Go Back   Naija Ryders > Main > Techie Forum
Connect with Facebook
Register Blogs FAQ Members List Guitar Hero Calendar Mark Forums Read

Reply
 
LinkBack Thread Tools Display Modes
Old 12-18-2006, 11:03 PM   #1 (permalink)
Registered User
 
djmightymike's Avatar
 
Join Date: Dec 2006
Location: Festac Town
Posts: 8,638
Points: 1,278,100,513.38
Bank: 0.02
Total Points: 1,278,100,513.40
Donate
Rep Power: 21474865 djmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legend



Default C++

12/17/06: 14:00p
While at work, doin a code review for a rookie C++ developer, i noticed a few design bugs that while able to compile and execute fine, are sure to cause you a lot of grief and make you use a lot of aspirins somewhere down the line of the develpoment cycle.

Smart Pointers - What are they and why do we care?

Smart pointers are objects that look and feel like pointers, but are smarter. What does this mean?
To look and feel like pointers, smart pointers need to have the same interface that pointers do: they need to support pointer operations like dereferencing (operator *) and indirection (operator ->). An object that looks and feels like something else is called a Proxy.

The simplest example of a smart pointer is auto_ptr, which is included in the standard C++ library. You can find it in the header .
Here is part of auto_ptr's implementation, to illustrate what it does:

template class auto_ptr
{
T* ptr;
public:
explicit auto_ptr(T* p = 0) : ptr(p) {}
~auto_ptr() {delete ptr;}
T& operator*() {return *ptr;}
T* operator->() {return ptr;}
// ...
};

As you can see, auto_ptr is a simple wrapper around a regular pointer. It forwards all meaningful operations to this pointer (dereferencing and indirection). Its smartness in the destructor: the destructor takes care of deleting the pointer.
For the user of auto_ptr, this means that instead of writing:

void foo()
{
MyClass* p(new MyClass);
p->DoSomething();
delete p;
}
You can write:
void foo()
{
auto_ptr p(new MyClass);
p->DoSomething();
}
And trust p to cleanup after itself.
What does this buy you?

Obviously, different smart pointers offer different reasons for use. Here are some common reasons for using smart pointers in C++.

Why: Less bugs
Automatic cleanup. As the code above illustrates, using smart pointers that clean after themselves can save a few lines of code. The importance here is not so much in the keystrokes saved, but in reducing the probability for bugs: you don't need to remember to free the pointer, and so there is no chance you will forget about it.
Automatic initialization. Another nice thing is that you don't need to initialize the auto_ptr to NULL, since the default constructor does that for you. This is one less thing for the programmer to forget.

Dangling pointers. A common pitfall of regular pointers is the dangling pointer: a pointer that points to an object that is already deleted. The following code illustrates this situation:

MyClass* p(new MyClass);
MyClass* q = p;
delete p;
p->DoSomething(); // Watch out! p is now dangling!
p = NULL; // p is no longer dangling
q->DoSomething(); // q is still dangling!

For auto_ptr, this is solved by setting its pointer to NULL when it is copied:
template
auto_ptr& auto_ptr:perator=(auto_ptr& rhs)
{
if (this != &rhs) {
delete ptr;
ptr = rhs.ptr;
rhs.ptr = NULL;
}
return *this;
}



WHY:Exception Safety
Let's take another look at this simple example:
void foo()
{
MyClass* p(new MyClass);
p->DoSomething();
delete p;
}
What happens if DoSomething() throws an exception? All the lines after it will not get executed and p will never get deleted! If we're lucky, this leads only to memory leaks. However, MyClass may free some other resources in its destructor (file handles, threads, transactions, COM references, mutexes) and so not calling it my cause severe resource locks.
If we use a smart pointer, however, p will be cleaned up whenever it gets out of scope, whether it was during the normal path of execution or during the stack unwinding caused by throwing an exception.

But isn't it possible to write exception safe code with regular pointers? Sure, but it is so painful that I doubt anyone actually does this when there is an alternative. Here is what you would do in this simple case:

void foo()
{
MyClass* p;
try {
p = new MyClass;
p->DoSomething();
delete p;
}
catch (...) {
delete p;
throw;
}
}
Now imagine what would happen if we had some if's and for's in there...

WHY:Garbage collection
Since C++ does not provide automatic garbage collection like some other languages, smart pointers can be used for that purpose. The simplest garbage collection scheme is reference counting or reference linking, but it is quite possible to implement more sophisticated garbage collection schemes with smart pointers

Why: STL containers
The C++ standard library includes a set of containers and algorithms known as the standard template library (STL). STL is designed to be generic (can be used with any kind of object) and efficient (does not incur time overhead compared to alternatives). To achieve these two design goals, STL containers store their objects by value. This means that if you have an STL container that stores objects of class Base, it cannot store of objects of classes derived from Base.
class Base { /*...*/ };
class Derived : public Base { /*...*/ };

Base b;
Derived d;
vector v;

v.push_back(b); // OK
v.push_back(d); // error
What can you do if you need a collection of objects from different classes? The simplest solution is to have a collection of pointers:
vector v;

v.push_back(new Base); // OK
v.push_back(new Derived); // OK too

// cleanup:
for (vector::iterator i = v.begin(); i != v.end(); ++i)
delete *i;
The problem with this solution is that after you're done with the container, you need to manually cleanup the objects stored in it. This is both error prone and not exception safe.
Smart pointers are a possible solution, as illustrated below. (An alternative solution is a smart container, like the one implemented in pointainer.h.)

vector< linked_ptr > v;
v.push_back(new Base); // OK
v.push_back(new Derived); // OK too

// cleanup is automatic
Since the smart pointer automatically cleans up after itself, there is no need to manually delete the pointed objects.
Note: STL containers may copy and delete their elements behind the scenes (for example, when they resize themselves). Therefore, all copies of an element must be equivalent, or the wrong copy may be the one to survive all this copying and deleting. This means that some smart pointers cannot be used within STL containers, specifically the standard auto_ptr and any ownership-transferring pointer.


Which one should I use?
Are you confused enough? Well, this summary should help.
Which: Local variables
The standard auto_ptr is the simplest smart pointer, and it is also, well, standard. If there are no special requirements, you should use it. For local variables, it is usually the right choice.

Which: Class members
Although you can use auto_ptr as a class member (and save yourself the trouble of freeing objects in the destructor), copying one object to another will nullify the pointer, as illustrated Below.
class MyClass
{
auto_ptr p;
// ...
};

MyClass x;
// do some meaningful things with x
MyClass y = x; // x.p now has a NULL pointer
Using a copied pointer instead of auto_ptr solves this problem: the copied object (y) gets a new copy of the member.
Note that using a reference counted or reference linked pointer means that if y changes the member, this change will also affect x! Therefore, if you want to save memory, you should use a COW pointer and not a simple reference counted/linked pointer.

Which: STL containers
As explained above, using garbage-collected pointers with STL containers lets you store objects from different classes in the same container.
It is important to consider the characteristics of the specific garbage collection scheme used. Specifically, reference counting/linking can leak in the case of circular references (i.e., when the pointed object itself contains a counted pointer, which points to an object that contains the original counted pointer). Its advantage over other schemes is that it is both simple to implement and deterministic. The deterministic behavior may be important in some real time systems, where you cannot allow the system to suddenly wait while the garbage collector performs its housekeeping duties.

Generally speaking, there are two ways to implement reference counting: intrusive and non-intrusive. Intrusive means that the pointed object itself contains the count. Therefore, you cannot use intrusive reference counting with 3-rd party classes that do not already have this feature. You can, however, derive a new class from the 3-rd party class and add the count to it. Non-intrusive reference counting requires an allocation of a count for each counted object.


Which: Big objects
If you have objects that take a lot of space, you can save some of this space by using COW pointers. This way, an object will be copied only when necessary, and shared otherwise. The sharing is implemented using some garbage collection scheme, like reference counting or linking.
Which: Summary
For this: Use that:
Local variables auto_ptr
Class members Copied pointer
STL Containers Garbage collected pointer (e.g. reference counting/linking)
Explicit ownership transfer Owned pointer
Big objects Copy on write

Conclusion
Smart pointers are useful tools for writing safe and efficient code in C++. Like any tool, they should be used with appropriate care, thought and knowledge. For a comprehensive and in depth analysis of the issues concerning smart pointers, I recommend reading Andrei Alexandrescu's chapter about smart pointers in his book Modern C++ Design.

Happy Coding!
djmightymike is offline   Reply With Quote
Old 12-18-2006, 11:11 PM   #2 (permalink)
Registered User
 
sapphire's Avatar
 
Join Date: May 2002
Location: ha!
Posts: 2,589
Points: 10,014.60
Bank: 604.82
Total Points: 10,619.42
Donate
Rep Power: 215999 sapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legendsapphire is a legend
Default

i thought the whole point of C++ is to get away from pointers and functional programming, into object oriented methods?
I might as well just code in C....thanks for the info though
__________________
If my father has stolen, I will...

** Attend the very best school in the world and walk shoulder high (Educational Investment)
** Organize charity fund just like the 'better life For Rural Women' and government officials will contribute more (...talk about the rich getting richer)
** Own properties in choice countries/ locations and drive 'tear rubber' vehicles (property Investment)
** Be the toast of the town where musician will sing praise me (Social well being)
** Owning a jet or airplane wouldn't be an issue (Ease of transportation)
** Streets/avenues will be named after me (grass root investment)
** Arrange prayers for my father in churches and mosques to ward off evil spirit and untimely death (Spiritual upliftment)
** Advice my father to marry more wives and take more chieftaincy tittles across the board (evenly distribution of wealth)
** Donate 'chairs' to tertiary institutions for under privilege children
** Have shares in blue chips companies
** Wouldn't have to struggle in life

But my father didn't have the opportunity to steal otherwise I wouldn't be in diaspora searching for the proverbial green pastures.

http://www.nigeriavillagesquare.com/...s-a-thief.html
sapphire is offline   Reply With Quote
Old 12-18-2006, 11:45 PM   #3 (permalink)
Registered User
 
djmightymike's Avatar
 
Join Date: Dec 2006
Location: Festac Town
Posts: 8,638
Points: 1,278,100,513.38
Bank: 0.02
Total Points: 1,278,100,513.40
Donate
Rep Power: 21474865 djmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legenddjmightymike is a legend



Default You're Kinda Right

w'sup sapphire, you're absolutely correct - the whole point of c++ was to get get away from functional programming, and some of the deficiencies of c style pointers. However, there are still lots of ways you can make your applications crash proof while using pointers and this is where smart pointers come in. making use of smart pointers provides you the freedom to not worry about garbage collection and memory/resource leaks. Aside from the efficiency/performance benefits of using c++, c++ can be made very safe, much safer than you could when using C. In fact smart pointers are not possible with C.

Using pointers in your applications come with several benefits, among which include

1. dynamic memory allocation
2. Access to Memory address spaces - This can be fun
3 Polymophism - creating a container that holds different types of objects

and like you said, pointers are known to be bad and responsible for most program crashes, however with C++, all these can be taken care of with good design methods. Hope this convinces u to still wanna code in C++, especially since you could make 6 figure salary coding in C++. it's a very effective language and that's why it's being used in a wide range of applications from video games graphics to interfacing with microdevices.

take care
djmightymike is offline   Reply With Quote
Old 12-19-2006, 07:01 AM   #4 (permalink)
The Nigerian Nightmare
 
crAzy Don's Avatar
 
Join Date: Mar 2005
Location: Somewhere...Dont know where exactly....But somewhere.....could be anywhere....definitely not everywhere...But somewhere.
Posts: 18,247
Points: 120,035.00
Bank: 0.02
Total Points: 120,035.02
Donate
Rep Power: 21474887 crAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legendcrAzy Don is a legend
Default

haha

memories.
__________________
NR .com Characters Welcome

"They coming for me, wan' see me fall
U know my story, I been through it all
Nights I felt like dyin’, but I ain’t cryin’
What didn’t kill me, made me strong as iron..."
~Jay-Z

Killin y'all niggaz on that lyrical shit
crAzy Don is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are Off
Pingbacks are Off
Refbacks are On

Points Per Thread View: 0
Points Per Thread: 0
Points Per Reply: 0
Forum Jump


All times are GMT +2. The time now is 04:16 PM.


Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.2.0
NaijaRyders