GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rating: Thread Rating: 2 votes, 5.00 average.
  #1  
Old 19-Aug-2005, 09:25
varunhome varunhome is offline
New Member
 
Join Date: Aug 2005
Location: Bangalore
Posts: 3
varunhome is on a distinguished road

Pointer Usage in C++: Beginner to Advanced


Description: The article covers pointer concepts and syntax in C++ in-depth. It uses a graded approach to increase difficulty level, with lots of illustrations and examples for beginners. It is also useful for advanced users to test knowledge of topics like "Dynamic Memory Allocation of Multi-dimensional Pointers" and "Deciphering of Lengthy Function Pointer Declarations."

The article can also be downloaded/viewed with multi-page formatting from:

Viewing link:
www.geocities.com

Download link:
www.geocities.com



Table of Contents

Chapter 1. Introduction: Objective, Target Audience and Article Revisons
Chapter 2. The & and * Operators
Chapter 3. Pointers: A First Example
Chapter 4. Arrays of Pointers
Chapter 5. Dynamic Allocation Of Memory: Single Dimension Pointers
Chapter 6. Linkages between Array And Pointer Syntax in C++
Chapter 7. Multi-Dimensional Pointers
Chapter 8. Using Pointers to Return Values From Functions
Chapter 9. Dynamic Memory Allocation: Multi-Dimensional Pointers
Chapter 10. Beginning with Function Pointers
Chapter 11. Deciphering (Long) Pointer Declarations
Chapter 12. Function Pointers and typedef






Chapter 1: Introduction: Objective, Target Audience and Article Revisons

C++ is a programming language that includes features of both low-level and high-level programming languages. It allows direct access to memory address locations but also provides advanced objext-oriented programming capabilities. It is also backward compatible with C. The flexibility that C++ provides comes with enormous complexity. My purpose in this article is to demystify the complexity that creeps into C++ from pointers. Personally, once I had understood pointers in-depth, learning the rest of what is necessary to be learnt in C++ was very easy.

The article is targetted at beginners and intermediate users of C++. However, it can be helpful to anyone who wants to test his knowledge of pointer syntax in C++. Especially, the chapters, "Chapter 11: Deciphering (Long) Pointer Declarations" and "Chapter 9: Dynamic Memory Allocation: Multi-Dimensional Pointers" would be very useful.

I have made two major changes since the previous version of the article. C++ syntax is now colour-coded through images and a couple of illustrations have been added to make examples easier to understand. The entire article uses more than a dozen examples to illustrate core concepts. It helps to practice these examples yourself as you read along. The source code is included with the download version. All examples have been tested with GNU C++ compiler v3.4.

Please send your suggestions on improving the article and making necessary corrections at varunhome@gmail.com. You can also find some more tips on my webpage at www.geocities.com. Follow the link labelled 'Technical Articles'.






Chapter 2: The & and * Operators

A pointer is a variable which stores the address of another variable. There are two important operators when working with pointers in C++: the address of (&) operator and the value of (*) operator. They have been overloaded in C++ so they may have different uses in different contexts.

How much storage space does a pointer consume? Use sizeof(ptr) without the '*' operator to determine the memory utilised on your system. Irrespective of datatype or whether the pointer points to a single variable or array, as a general rule, pointers must use the same amount of memory space.

The & operator gives us the address of a variable and * gives us the value of a variable at a specified address. For example,

CPP / C++ / C Code:
#include <iostream>

using namespace std;
/*
	ex1.cpp
*/

int main ( )
{

 	int i = 10;

 	cout << "The value of variable i is " << i << "\n";

	cout << "The memory address of i is " << &i << "\n";
	/*
		Prints the memory address in hexadecimal format.
	*/

	cout << "The value of variable i using * operator is " << *(&i) << "\n";
	/*
		The * operator gives the value when provided with a memory address. 
		Note that the data type is inferred from the variable name.
	*/

	return (0);
}




Chapter 3: Pointers: First Example

Here is a simple example of using pointers in C++.

CPP / C++ / C Code:
/*
	ex2.cpp
*/

#include <iostream>

using namespace std;

int main ()
{
	int i = 10;
	int *x = &i;
	int *y;
	/*
		x stores the address of variable i. Pointer assignment could also be done as:
	*/
	y = &i;

	cout << "The pointer x is stored at the memory address "<< &x << "\n";
	cout << "The pointer x stores the memory address of i: " << x << "\n";
	/*
		Contrast the difference between the memory address of the pointer 
		and the memory address it stores.
	*/

	cout << "The value of i accessed through pointer x is " << *x << "\n";
	

	/*
		Now we manipulate the value of i using pointer x.
	*/
	*x = *x + 1; /* increments i by 1 */

	cout << "i (through pointer) = " << *x << " which equals i (direct access) " << i << "\n";
	/*
		A pointer does not create a copy of the variable it points to.
	*/

	cout << "The memory allocated to the pointer x is " << sizeof(x) << " bytes.\n";
	return (0);
}


A diagram illustrating relationships between different variables in the above example should help clarify concepts.




Chapter 4: Arrays of Pointers

Just as we have arrays of variables, so also we have arrays of pointers. For example,
Quote:
int *p[5];

declares an array of five pointers to integer variables. More details on pointer syntax are provided in "Chapter 11: Deciphering (Long) Pointer Declarations". Each pointer in turn stores the memory address of an integer on its own. Each pointer may even store the base address of an array of integers. Let us understand the use of arrays of pointers with an example.

CPP / C++ / C Code:
/*
	ex3.cpp
*/

#include <iostream>

using namespace std;

char ch1 = 'a', ch2 = 'b';

char ch3[4] = { 'c', 'd', 'e', 'f' };

char *ptr[3];

int main ()
{
 	ptr[0] = &ch1;
	ptr[1] = &ch2;
	ptr[2] = ch3;
	/*
		Base address of array ch[3] is stored at ptr[2]. Equivalently,
				ptr[2] = &ch3[0];	
	*/

	
	/*
		Refresher of topics covered in previous examples. What is the output?
	*/
	cout << "Initial characters stored in ptr[0] and ptr[1]: " << *ptr[0] << " " << *ptr[1] << "\n";
	*ptr[0] = 'z';
	*ptr[1] = 'y';
	cout << "Final characters stored in ptr[0] and ptr[1]: " << *ptr[0] << " " << *ptr[1] << "\n";

	
	return (0);
}





Chapter 5: Dynamic Allocation Of Memory: Single Dimensional Pointers

In the above example, we did not allocated memory for the data pointed to by the pointer ptr[2]. This is because it points to the array ch3 for which memory has already been allocated. However, in some cases, we may want a pointer variable to point to an unnamed memory location. We achieve this through the use of new and delete operators. Here is a simple example followed by a more complex example:

CPP / C++ / C Code:
/*
	ex4.cpp
*/

#include <iostream>

using namespace std;

int i = 0;

int *ptr1;

int main ()
{
 	ptr1 = new int;
	/*
		 'new' allocates memory for an unnamed integer. 
		 The base memory address of the variable is then assigned to ptr1. 
		 We can freely access the unnamed variable through the pointer.
	*/
	*ptr1 = 10;

	*ptr1 = 2 + *ptr1;

	cout << "Dynamic memory allocation: Value of ptr1 is " << *ptr1 << "\n";

	
 	/*
		Free up allocated memory by dereferencing. 
		Use the pointer once more by assigning it another memory address.
	*/
	delete ptr1;

	
	/*
		Same pointer is now allocated the base address of an array
	*/
	ptr1 = new int[3];


	/*
		The unnamed array can be easily accessed using the pointer ptr1. 
		There is more than one way to do this.
	*/
	*(ptr1+0)=2;
 	*(ptr1+1)=4;
	ptr1[2]=6;

	
	cout << "Printing array of pointers: \n";
	for(i=0;i<3;i=i+1)
	{
		cout << "*(ptr1+" << i << ") = " << *(ptr1+i) << "\n";		
	}

	
	/*
		Note that array notation is used to access pointer.
	*/
	cout << "Reprinting array of pointers: \n";
	for(i=0;i<3;i=i+1)
	{
		cout << "ptr1[" << i << "] = " << ptr1[i] << "\n";
	}
	
	
	/*
		Free up memory by dereferencing the pointer. Array size need not be specified. 
		Deleted memory is returned to free store.
	*/
	delete[ ] ptr1;
	
	
	return (0);
}


One thing to remember is the use of dynamic memory allocation in classes. When we create a class in C++, the compiler automatically creates four member functions, even if we don't create them:

Quote:
1. The default (no argument) constructor
classname& classname ()

2. The copy constructor
classname& classname (classname&)

3. The assignment (=) operator
classname& operator=(classname&)

4. The destructor
~classname ()


When we make a copy of a class containing a pointer, the pointer gets copied but the data that the pointer points to does not get copied. Therefore, always remember to make a copy of the data using dynamic memory allocation and store it in the pointer of the class copy. When overloading the copy constructor, you should therefore preferably overload the assignment operator also.





Chapter 6: Linkages Between Arrays And Pointer Syntax in C++

Array and pointer syntax is generally inter-changable in C++. The next example reinfroces these linkages covered briefly in the previous example.

CPP / C++ / C Code:
/*
	ex5.cpp
*/

#include <iostream>
using namespace std;

int arr[3] = {10, 15, 20};

int *ptr = new int[3];

int main ()
{
	*(ptr+0) = 2;
	ptr[1] = 4;
	*(ptr+2) = 6;
	/*
		Shows how to access pointers using either array or pointer notation
	*/

	/*
		In the same way, an array can also be accessed using pointer notation.
	*/
	cout << "arr[0] using array notation = " << arr[0] << "\n";
	cout << "arr[1] using pointer notation = " << *(arr+1) << "\n";

	/*
		Now we will access the base address of the array that the pointer points to.
	*/
	cout << "Base address of array ptr points to: " << ptr << "\n";
	/*
		Now we will access the base address of the array arr
	*/
	cout << "Base address of array arr is: " << arr << "\n";
	
	/*
		The above example highlights the close linkages between pointer and array notations in C++
	*/

	return (0);
}




Chapter 7: Multi-Dimensional Pointers

Just as we can have multi(2, 3, 4, .....)-dimensional variables, we can have multi-dimensional pointers also. A simple example is shown below:

CPP / C++ / C Code:
/*
	ex6.cpp
*/

#include <iostream>

using namespace std;

int **ptr2;
int *ptr;
int i = 10;

int main ()
{
	/*
		What does *ptr print now?
 	*/
	ptr = &i;

	/*
		Now we assign the base address of ptr (the pointer itself, 
		not what it points to) to ptr2
	*/
	ptr2 = &ptr;

	/*
		The same variable can be accessed through multi-dimensional pointer also
	*/
	cout << "Accessing i through i: " << i << "\n";
	cout << "Accessing i through ptr: " << *ptr << "\n";
	cout << "Accessing i through ptr2: " << **ptr2 << "\n";

	return (0);
}

You will find the above syntax used often in passing parameters to functions and accepting return values. Let us understand this through an example in the next chapter.

The usage of the above code can be easily understood from the following diagram. You should try and develop a diagram of your own to understand the example in Chapter 9: Dynamic Memory Allocation: Multi-Dimensional Pointers.





Chapter 8: Using Pointers To Return Values From Functions

I assume that you are aware of these keywords which are used in next example:

1. exit (int) : end program
2. break : stop execution of loop
3. continue : stop loop execution at present value, resume from next value
4. return : used to stop function execution. Can also be used without parameters in functions returning void.

CPP / C++ / C Code:
/*
	ex7.cpp
*/


#include <iostream>

using namespace std;

/*
  Function declaration.
*/
int * sum (int *i, int *j);

/*
   Function definition.
*/
int * sum (int *i, int *j)
{
 	int *result = new int;
	 
 	*result = *i + *j;

	return (result);
	/*
	 	The return value from function is equivalent to:
			int *unnamed = result;
	*/
}


int main ()
{
	int p = 10, q = 20;

	int *r = sum(&p, &q);
	/*
		The pointer r stores the base address of the memory allocated with 
		new operator in the function sum. 
	*/

	cout << "The sum is " << *r << "\n";

	return (0);
	
	/*
		Since memory is not being deleted with delete operator, a memory leak is created. 
		Never do it in practice.
	*/
	
}





Chapter 9: Dynamic Memory Allocation: Multi-Dimensional Pointers

Here is another more complicated example of dynamic memory allocation. We will allocate space for a two dimensional array of size [3][4] and manipulate it with a pointer.

CPP / C++ / C Code:
/*
	ex8.cpp
*/

#include <iostream>

using namespace std;

int **ptr;

int main ()
{
	ptr = new int *[3];
	/*
		Statement is read as: "ptr stores the base address of an array of three 
		pointers to an int or int array". More on this in chapter on 
		"Deciphering Pointer Declarations".
	*/

	
	for(int i=0;i<3;i=i+1)
	{
	 	*(ptr + i) = new int[4];
	}
	/*
		The above loop can also be replaced with:
			ptr = new int[3][4]; 
	*/

	
	/*
	 	Now we can manipulate the allocated memory.
 	*/
 	for(int i=0;i<3;i=i+1)
 	{
		for(int j=0;j<4;j=j+1)
	 	{
			*(*(ptr+i)+j) = i + j;
			/*
				This can also be written as:
					ptr[i][j] = i + j;
			*/

			cout << "ptr[" << i << "][" << j << "] = " << ptr[i][j]; cout << "\n";
		}
	}


 	/*
		Free the allocated memory now. 
		The number of delete statements must match number of new statements. 
		This is merely a copy-paste of the previous section, where new operator 
		has been replaced with delete.
	*/
	for(int i=0;i<3;i=i+1)
	{
		delete[] *(ptr+i);
	}
	delete[] ptr;

	return (0);
}


The above example when used with three dimensional pointers to create an array of size [2][3][4] looks as follows:

CPP / C++ / C Code:

/*
 	ex9.cpp	
	Example 8 extended to three-dimensional pointers. 
	No detailed comments included.
*/

#include <iostream>
using namespace std;

int ***ptr;

int main ()
{
	ptr = new int **[2];

	for(int i=0;i<2;i=i+1)
	{
		*(ptr+i) = new int *[3];
	 	for(int j=0;j<3;j=j+1)
		{
			*(*(ptr+i)+j) = new int[4];
	 	}
	}


	/*
		Access the allocated memory.
	*/
	cout << "Summing values within [ ], assigning to pointer and printing. " << "\n";
	for(int i=0;i<2;i=i+1)
	{
		for(int j=0;j<3;j=j+1)
		{
	 		for(int k=0;k<4;k=k+1)
			{
				*(*(*(ptr+i)+j)+k) = i+j+k;
				cout << "ptr[" << i << "][" << j << "]["; cout << k << "] = ";
				cout << *(*(*(ptr+i)+j)+k) << "\n";
			}
		}
	}


	/*
 		Delete the allocated memory.
 	*/
	for(int i=0;i<2;i=i+1)
	{
		for(int j=0;j<3;j=j+1)
		{
	 		delete[] *(*(ptr+i)+j);
	 	}
		delete[] *(ptr+i);
	}
	delete[] ptr;

	return (0);
}


When dynamic memory allocation fails, an exception is thrown. You would normally want to catch the exception and halt program execution. However before exceptions were used in C++ (or if you use the nothrow version of new), whenever dynamic allocation failed, the pointer stored a NULL value. In that case the following check would be used:

Quote:
int *ptr = new int;

if(!ptr)
{
//error
}





Chapter 10: Beginning with Function Pointers

Just as we have pointers to the basic datatypes, we have pointers to classes and structures also. They are used in exactly the same way as pointers to the basic datatypes. That is why we will not discuss how to use them here. We will instead concentrate on the use of function pointers.

Function pointers are pointers to functions. They are used when we do not know at the time of compiling a program the function we will need to call. They are often used in GUI libraries to execute a specified function when a particular signal (input) is received. The rules defining function pointers are the same as with other pointers. However, the declaration looks very different.





Chapter 11: Deciphering (Long) Pointer Declarations

This chapter explains rules to follow for deciphering pointer declarations. These are particularly important for function pointers.

1. Start with the name that will identify the pointer, which is known as the identifier.

2. Move to the right until you encounter a right-parantheses [symbol = ")" ] or reach the end. Do not stop if the () brackets are used to pass parameters to a function. Also do not stop on encountering brackets used with arrays: [ ].

3. Now go left of the identifier to continue deciphering the declaration. Keep going left until you find a left-parantheses [the symbol "(" ] or reach the end. Do not stop if the brackets are used to pass parameters to a function.

4. The whole interpretation should be a nice long sentence.


Here are a few examples to make the process clear:




Chapter 12: Function Pointers and typedef

Let us see an example of function pointers.

CPP / C++ / C Code:
/*
	ex10.cpp
*/

#include <iostream>

using namespace std;


/*
	Function definition.
*/
int sum (int a, int b)
{
 	return (a + b);
}


int (*ptr_sum) (int, int) = &sum;
/*
 	ptr_sum is a pointer to a function taking two ints as arguments and returning an int.
*/



int main ( )
{
	int a, b;
	cout << "Enter two ints (separated by whitespace): ";
	cin >> a >> b;

	
	/*
		Here we check if the function pointer really points to the correct function.
	*/
	if(ptr_sum != &sum)
	{
		cout << "Crazy error";
		//exit (0);
	}

	
	/*
		Here we make use of the function pointer.
	*/
	int result = (*ptr_sum) (a,b);
	cout << "Sum is " << result << "\n";

	return (0);

}


Let us conclude with the same example implemented with a typedef declaration.

CPP / C++ / C Code:
/*
	ex11.cpp
*/

#include <iostream>

using namespace std;



int sum (int a, int b)
{
	return (a + b);
}
typedef int (*ptr_sum_type)(int, int);



int main ( )
{
	int a, b;

	
	/*
		Now we create an object (pointer) using the typedef declaration made earlier
	*/
	ptr_sum_type ptr_sum= &sum;

	
	cout << "Enter two ints (separated by whitespace): ";
	cin >> a >> b;

	
	/*
		Here we make use of the function pointer.
	*/
	int result = (*ptr_sum) (a,b);
	cout << "Sum is " << result << "\n";

	
	return (0);
}
Last edited by LuciWiz : 20-Aug-2005 at 10:40. Reason: Formatting needed
 
 

Recent GIDBlogCompress Your Web Site by gidnetwork

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
2D arrays:dynamic allocation and freeing bravetanveer C Programming Language 51 03-Jun-2012 18:45
[Tutorial] Pointers in C (Part II) Stack Overflow C Programming Language 0 27-Apr-2005 17:36
[Tutorial] Pointers in C (Part I) Stack Overflow C Programming Language 1 08-Apr-2005 18:35

Network Sites: GIDNetwork · GIDApp · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 03:23.


vBulletin, Copyright © 2000 - 2013, Jelsoft Enterprises Ltd.