Showing posts with label Pointers. Show all posts
Showing posts with label Pointers. Show all posts

Wednesday, 27 January 2010

Memory Allocation example for Double Pointer of a class

The following program should be self explanatory:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Program to demonstrate memory allocation to double pointers
#include<iostream>

using namespace
std;

//Class named NewClass
class NewClass
{

public
:
int
a;
int
* b;
void
* c;
};


//List Structure containing multiple NewClass objects
struct NewClassList
{

int
numOfObjects;
NewClass** Objects;
};


int
main()
{

//Create NewClassList with 4 objects with following values:
//1, 10, 100; 2, 20; 200; 3, 30, 300; 4, 40, 400;
NewClassList someList;
someList.numOfObjects = 4;
//someList.Objects = new NewClass*; //1. Common mistake in allocating memory
someList.Objects = new NewClass*[someList.numOfObjects];

someList.Objects[0] = new NewClass;
someList.Objects[0]->a = 1;
someList.Objects[0]->b = new int(10);
someList.Objects[0]->c = (void*) new int(100);

someList.Objects[1] = new NewClass;
someList.Objects[1]->a = 2;
someList.Objects[1]->b = new int(20);
someList.Objects[1]->c = (void*) new int(200);

someList.Objects[2] = new NewClass;
someList.Objects[2]->a = 3;
someList.Objects[2]->b = new int(30);
someList.Objects[2]->c = (void*) new int(300);

someList.Objects[3] = new NewClass;
someList.Objects[3]->a = 4;
someList.Objects[3]->b = new int(40);
someList.Objects[3]->c = (void*) new int(400);

//Printing the outputs
for(int i = 0; i < someList.numOfObjects; i++)
{

cout<<"Iteration = "<<i;
cout<<": a = "<<someList.Objects[i]->a;
cout<<": b = "<<*(someList.Objects[i]->b);
cout<<": c = "<<*((int*)someList.Objects[i]->c)<<endl;
}


//Clear all the memory allocation
for(int i = 0; i < someList.numOfObjects; i++)
{

delete
someList.Objects[i]->b;
delete
someList.Objects[i]->c;
delete
someList.Objects[i];
}

delete
[] someList.Objects;
return
0;
}





The output is as follows:

Tuesday, 19 January 2010

The Unmanaged Pointer problem

This is an interesting problem from More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions by Herb Sutter. See Amazon link at the bottom of the post.

In your travels through the dusty corners of your company's code archives, you find the following code fragment:

// Example 20-2
//

// In some header file:
void f( T1*, T2* );

// In some implementation file:
f( new T1, new T2 );

Does this code have any potential exception safety problems?

On a personal note, I have seen people trying to do as much as possible on a single line thinking that they are writing optimised code. This may be true in some very rare instances but in most of the cases this is not true. Performing multiple operations in a single statement can cause side effects like memory leaks or incorrect operation, it can also make the code less readable and can cause difficulty in debugging.

Going back to the problem at hand, according to Herb Sutter there are several potential exception safety problems with the above code. An expression such as new T1 is called, simply enough, a new-expression. Recall what a new-expression really does:

* It allocates memory;
* It constructs a new object in that memory; and
* If the construction fails because of an exception the allocated memory is freed.

So each new-expression is essentially a series of two function calls: one call to operator new() (either the global one, or one provided by the type of the object being created), and then a call to the constructor.

So in case of a function defined as f( expr1, expr2 );

consider what happens if the compiler decides to generate code as follows:

1. allocate memory for the T1
2. construct the T1
3. allocate memory for the T2
4. construct the T2
5. call f()

The problem is this: If either step 3 or step 4 fails because of an exception, the C++ standard does not require that the T1 object be destroyed and its memory deallocated. This is a classic memory leak, and clearly Not a Good Thing.

Another possible sequence of events is the following:

1. allocate memory for the T1
2. allocate memory for the T2
3. construct the T1
4. construct the T2
5. call f()

This sequence has not one, but two exception safety problems with different effects:

If step 3 fails because of an exception, then the memory allocated for the T1 object is automatically deallocated (step 1 is undone), but the standard does not require that the memory allocated for the T2 object be deallocated. The memory is leaked.

If step 4 fails because of an exception, then the T1 object has been allocated and fully constructed, but the standard does not require that it be destroyed and its memory deallocated. The T1 object is leaked.

As I have mentioned that performing multiple operations in a single statement is potentially harmful. If you have no option and want to go the above way then the above mentioned problems can be avoided by the use of auto_ptr. See here.

Check out the book on Amazon:



Monday, 1 June 2009

A look at Smart Pointers

There is lot of confucion, misconceptions and misunderstanding regarding smart pointers. After looking at various books and tutorials, i got quite confused till I managed to figure out what they exactly are:

Smart pointers are objects that look and feel like pointers, but are smarter.

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 object, or just proxy.

To be smarter than regular pointers, smart pointers need to do things that regular pointers don't. What could these things be? Probably the most common bugs in C++ (and C) are related to pointers and memory management: dangling pointers, memory leaks, allocation failures and other joys. Having a smart pointer take care of these things.

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 , or take a look at Scott Meyers' auto_ptr implementation. Here is part of auto_ptr's implementation, to illustrate what it does:

template <class T> 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.

Lets look at a proper example:

#include<iostream>
#include<memory>


using namespace
std;

class
A
{

public
:
int
*data;
string name;
A(string n): name(n)
{

cout<<"Constructor of A = "<<name.c_str()<<" called "<<endl;
data = new(int);
};

A(string n, int x): name(n)
{

cout<<"Overloaded Constructor of A = "<<name.c_str()<<" called "<<endl;
data = new(int);
*
data = x;
};
~
A()
{

cout<<"Destructor of A = "<<name.c_str()<<" called "<<endl;
delete
(data);
data = this->data;
data = NULL;
}

A* operator ->() { return this;};
};


void
someFunc()
{

auto_ptr<A> a1(new A("a1"));
cout<<"Enter a number and press enter: ";
cin >> (*a1->data);
cout << "a1->data = "<<*a1->data<<endl;

A a2("a2",25);
A *a3 = new A("a3");
}


int
main()
{

cout<<"Before SomeFunc()"<<endl;
someFunc();
cout<<"After SomeFunc()"<<endl;
return
0;
}
The output is as follows:


As you have probably noticed, the instance a3 is never deleted and will cause memory leaks. Using smart pointer would automatically delete the instance a3 and the memory associated with it.

You can read Smart Pointers in much more detail at the References below.

References:
http://ootips.org/yonat/4dev/smart-pointers.html
http://www.geekpedia.com/tutorial47_Smart-Pointers---Part-1.html
http://www.geekpedia.com/tutorial59_Smart-Pointers---Part-II.html