In this article we will look in details of declaration and initialization of a pointer variable. As we know, pointers are one of the most important and strongest features of C++, it becomes necessary to know about them in details.

 

DECLARATION AND INITIALIZATION OF POINTERS

Pointer variables are declared like normal variables except for the addition of the unary * character. The general form of a pointer declaration is as follows :


data_type  *var_name;


Here data_type is any valid C++ data type and var_name is the name of the pointer variable.


See some examples of declarations :

int * iptr;                   // creates an integer pointer iptr

char * cptr;               // creates a character pointer cptr

float * fptr;               // creates a float pointer fptr


When we say that iptr is an integer pointer, it means that the memory location being pointed to by the pointer can hold only integers values. In other words, it can be stated that iptr is a pointer to integer. Similarly, in the above given declarations, cptr is a pointer to a character and fptr is a pointer to floating point value.

 

Thus, the base type of the pointer defines what type of variables the pointer can point to.

 

Note: Technically, any kind of pointer can point anywhere in the memory. However, all pointer arithmetic is done relative to its base type, so it is important to declare the pointers correctly. This is the reason why compiler shows error when we try to assign variable of a different data type to a pointer of different base type.

 

How much space does a pointer take?

As a pointer is also a proper data type (derived), it takes space in the memory just like any primitive data type. But the size of a pointer variable is not dependent on its base type. Every pointer, irrespective of its base type, takes 8 bytes of space in memory(64 bit system).

 

Does an empty pointer take space?

Well, yes. As soon as a pointer is created, it is given an 8 bytes space in the memory. When we assign the address of another variable to it, it simply stores the address value. It is similar to creating, say an int variable and then storing a value to it. Even if no value was assigned to that int variable, it would still take up the space. The memory allocating statement is the declaration and not initialization.

 

Special Operators for Pointer handling

Two special operators * and & are used with pointers.

The & is a unary operator that returns the memory address of its operand.

For example,


int i = 25;              // declares an int variable i

int * iptr;              // declares an int pointer iptr

iptr = &i;              // stores the memory address of i into iptr

 

The above given assignment statement stores the memory address if i (& returns address of its operand) into iptr so that iptr is now pointing to the memory location of i. The expression &i will return an int pointer value because i is integer type. Similarly, if ch is a character type variable, &ch will return a character pointer.

 

To understand the above assignment better, assume that variable i uses memory location 1000 to store its value. And the value stored in i is 25, then after the statement iptr = &i, iptr will have the value 1000.

Following figure illustrates this concept.

 

DECLARATION AND INITIALIZATION OF POINTERS

The second pointer operator, *, does the reverse of &. The unary operator * returns the value of the variable located at the address following it.

For example, if iptr contains the memory address 1000, then * iptr will return the value stored at location 1000.

Following figure illustrates this concept.

Using ‘*’ operator to change or access the value being pointed to by pointer is called Dereferencing.

Notes:

The pointer operator * (called “value at” sign) is the same symbol as multiply operator * and the pointer operator & (called “address of” sign) is same as bitwise AND operator &. But these operators have no relationship to each other. Both pointer operators * and & have a higher precedence than all other arithmetic operators except unary minus, with which they have equal precedence.

The operand of & operator can be any variable or object whose address we need, but the operand of * operator can only be a pointer variable. 

 

Pointers pointing to incorrect data types

The pointer variables must always point to the correct type of data. For instance, when a pointer is declared to be of type int, the compiler assumes that the address being pointed to by this pointer, will hold integer values.

Consider the following code fragment :

double a,b ;

int * iptr;

cin>>a;                      // read float value for a

iptr = & a;                 // store the address of a into iptr

b = *iptr;                  // store the value being pointed to by iptr into b

 

The above code is intended to assign the value of a to b through the use of pointers, but it will not produce the desired result. Because iptr is an integer pointer, only 4 bytes (int size is generally 4 bytes) of information will be transferred to b, not the 8 bytes that normally make up a double type value. Thus, making a pointer point to incorrect type of data may lead to loss of information.

 

The “NULL” Pointer Value

A pointer variable must not remain uninitialized since dereferencing uninitialized pointers cause the system crashing. Even if you do not have any legal pointer value to initialize a pointer, you can initialize it with NULL pointer value. Assigning NULL to a pointer initializes it to a value which is not a legal pointer but it saves you from the ‘Big’ problem of uninitialized pointers. A program can later test a pointer against NULL (the zero pointer) to see whether it contains a legal pointer or not.

For example, consider the following code snippet :

int * iptr = NULL;   // iptr gets initialized with NULL

 …………………. ;

if(iptr != NULL)

{….                              // use the pointer if it points to some legal address

}

Important :

The expression (iptr != NULL) is equivalent to expression (iptr). The zero pointer NULL is defined in the standard header file stddef.h. NULL is internally mapped as int 0 (zero).

 

nullptr – New addition in C++11 standard

Before the release of C++11 standard, defined as NULL filled the role of null pointer. But in C++11, a new keyword namely nullptr has been introduced, which is a distinguished null-point constant. So, now on (provided you are using C++11 standard compilers), you can initialize your pointers with nullptr.

For example,

char * cptr = nullptr;

int * iptr = nullptr;

 

Difference between NULL and nullptr is that –


NULL is not defined by C++, it is programmer or compiler defined whereas nullptr has been defined by C++ as a legal null pointer.


NULL is internally mapped as int 0 (zero) whereas nullptr is a legal empty pointer which is implicitly convertible and comparable to any pointer-type.

 

The inclusion of nullptr also removes a major problem.

Suppose you have two overloaded functions

int f1 (char *) ;

int f1 (int)  ;

And we have two pointers as

char * cptr1 = NULL ;

char * cptr2 = nullptr ;

Now the function call f1(cptr1) would always map to f1(int) and not f1(char *) as NULL is internally mapped as an int.

But f1(cptr2) will always map to the function f1(char *).

 

 

 

 

 

 

Do not stop here. Read all articles related to C++ here.

If you have any doubts, queries or suggestions for the website, please comment on this post.

If you want to contribute any article for the website, feel free to share it on coding.nkcoder@gmail.com. We will publish it on the website with your name.

Download the pdf form of this article here.

 

Related Topics :

 

Introduction to Pointers

Static and Dynamic Allocation of Memory

Pointer Arithmetic

Dynamic Allocation Operators

Memory Leaks

Pointers & Constants