Monday, Dec 11th

Last update12:59:40 PM GMT

Pointers: Basics

Write e-mail

Concept of pointers is one thing that beginners find difficult to understand and if not clear, the road ahead is difficult to walk.

argaiv1865

This is the first in the series of articles that I will be writing to explain the concept of pointers to the best of my ability. You must have had at least one look at any text book to know that a pointer variable is a variable that holds a memory address.

In C when we define a pointer variable we do it by preceding its name with an asterisk. We also give our pointer a type which refers to the type of data stored at the address we will be storing in our pointer. 

int *ptr;

ptr is the name of our pointer variable (signalled to compiler by the *) . The int says that we intend to use our pointer variable to store the address of an integer. Such a pointer is said to "point to" an integer.But at the moment, ptr has no known value, that is we haven't stored an address in it in the above declaration. It is UNINITIALISED. It will be containing any random garbage value and accesisng it will give unpredictable results. To make sure that a pointer does not point anywhere we assign it to NULL.

ptr = NULL;

NULL Pointer

The actual bit pattern used for a null pointer depends on the specific operating system on which the code is compiled and hence it may or may not evaluate to zero. To make the source code compatible between various compilers on various systems, a macro is used to represent a null pointer. It is named NULL. Thus, setting the value of a pointer using the NULL macro, as with an assignment statement such as ptr = NULL, guarantees that the pointer has become a null pointer. Similarly, like we can test for an integer value of zero, we can test for a null pointer  as well using

if (ptr == NULL).

The programmer must note that a NULL pointer (that is ptr=NULL) means that the pointer is not pointing anywhere. Irs prime use is to avoid accidental modification of values stored at a memory address to which pointer may point to. Assigning a pointer to NULL ensures that subsequently if we try to access value stored at the location pointed to by it will return a NULL POINTER ASSIGNMENT ERROR like in the below case:

int *ptr =NULL;
*p = 3; //gives NULL POINTER assignment error

A NULL pointer is different from an unitialised pointer. A pointer if not initialised will point to any garbage address and is too dangerous and hence it is always suggested to intialise it to a valid address or to NULL as the case be.

PS: Pointers declared globally (outside any function) are automatically initialised to NULL (similar to the way global variables are initialised to 0).

Suppose now that we want to store in ptr the address of some our integer variable num. To do this we use the unary & operator and write: 

int num =2;
ptr = #

What the & operator does is retrieve the lvalue that is, memory address of num, even though num is on the right hand side of the assignment operator '=', it copies that to the contents of our pointer ptr. Now, ptr is said to "point to" an integer num.

The "dereferencing operator" is the asterisk and it is used as follows:

*ptr = 3;

This copies 2 to the address pointed to by ptr. Thus if ptr "points to" (that is, contains the address of) num, the above statement will set the value of num to 2. That is, when we use the '*' this way we are referring to the value stored at the address to which the ptr is pointing to, not the value of the pointer itself.

pointers

Pointer Arithematic

Shouldn’t we question here, why does the compiler need to know the datatype of the variable to whose address the pointer is pointing to? In the above example itself what if we increment the pointer ptr, that is,

ptr ++;

Here its not like ptr will now start pointing to the next byte. Since now the compiler knows that the location where ptr is pointing to belongs to an int and an int stores 4 bytes. Hence incrementing ptr causes the pointer ptr to point to a memory address 4 bytes ahead of the current one. The same goes for other data types such as floats, doubles, or even user defined data types such as structures. This is obviously not the same kind of "addition" that we normally think of. In C it is referred to as addition using "pointer arithmetic". So ptr ++, ++ ptr and ptr +1 are valid operations and same as well, though the point in the program when ptr is incremented may be different. Incrementing a pointer using the unary ++ operator, either pre- or post-, increments the address it stores by the amount equal to sizeof(type) where "type" is the type of the object pointed to. (i.e. 4 for an integer).

Same rules apply for decrementing the pointer.

Moreover, while subtraction of two pointers is a valid operation, multiplication, addition are not. Why? Well, If you and I live on the same street, the difference of our house numbers is some sort of indication of the distance between our houses. But what meaning is there in the sum of our house numbers? ;-)

VOID Pointer

A Void pointer is a special type of pointer of void and denotes that it can point to any data type. We can not make a pointer declared to be pointing to an integer to point to a float. For eg:

int x;
float f;
int * ptr;
ptr=&f; // This is invalid and gives error at compilation.

However, this is where void pointer is used. Void is used as a keyword here and can be made to point to any datatype.

So changing int pointer above to void pointer: void * ptr; makes both ptr =&x and ptr = &f as valid statements.:-).

However there are few restrictions associated with void pointer:

  • The data pointed to by void pointer cannot be directly dereferenced (which is logical, since there is no type to dereference), and hence its necessary to type-cast the address in the void pointer to some other pointer type that points to a concrete data type like int, char etc before dereferencing it.
  • While you can assign any pointer to a voud pointer, but dont expect  more liberty.The reverse is not true. You cannot assign a void pointer to an int pointer.
  • Pointer arithematic is not allowed on void pointers.

A great use of void pointers is in C memory allocation functions (malloc etc) and also in virtual functions VTABLEs.

GOTO: Pointers:The Array Relation!!

Share this post



Add comment

Please refrain from using slang or abusive language in the comments.
To avoid waiting for your comment to be published after being reviewed, please log in as a registered user.


Security code
Refresh

Web Hosting