• No results found

Be careful with Pointers

In document C++ Basics to Advanced (Page 195-199)

This section deals with some of the mistakes that can be committed using pointers.

1.) Make sure that your pointer variable points to the correct type of data. If you declare

a pointer of type integer then make sure that the address it holds contains an integer.

float y = 6.6; // y is a float quantity int * p; // p points to an integer type

p = &y; // Wrong - p is supposed to point to an integer but y is a float.

2.) Be careful while making multiple pointer declarations.

Suppose you want to declare two pointers: p1 and p2 that point to an integer data type. You might be tempted to write the declaration as:

int * p1, p2;

Seems right, doesn't it? This declaration is wrong. This will declare p1 as a pointer pointing to integer type. The compiler will consider p2 as an integer and not a pointer. Since * precedes p1, the compiler considers only p1 as a pointer. Hence be careful while declaring pointers.

3.) A pointer should store an address.

Consider an extract from a program given below:

int *p; // marks is a pointer that points to data type long. *p = 82; //wrong

Note the point that we have not yet stored any memory address in marks.

When a pointer is created the compiler will allot memory to hold an address. It will not allocate memory to hold the data to which the address points. Perhaps it's a bit confusing. The problem with our program is that we are supposed to store an address in p. After storing an address in p you can then store some value at that address. What we have done is that we haven't assigned any address to p. Without an address you can't store a value. Hence the value 82 cannot be placed anywhere. A pointer which is not initialized is called a ‘dangling pointer’.

4.) Pointers are not the same as integers. Pointers hold a memory address and hence they

cannot be multiplied or divided. Pointer addition will be discussed later.

5.) Not advisable to assign a memory address on your own (unless you are really sure of

what you are doing). Consider the following:

int * p; //Correct p = 006AFDF4; //wrong

A pointer stores a memory address. So you may think that the second line is correct. We have assigned a hexadecimal number to p (which is a pointer). The problem is that the compiler doesn't know that 006AFDF4 is a memory address. You may get an error message saying ‘data type mismatch’. Instead you can write it as:

p = (int * ) 0x006AFDF4; // This is correct.

This is correct because we are forcibly telling the compiler that this is a memory address (you’ll learn about forcing in the section on ‘casting’).

6.) Some programmers prefer to initialize a pointer to NULL. NULL is a predefined

constant with a value of 0. When initialized to null, the memory address stored in the pointer will be: 0x00000000. The code below will compile but it is an erroneous code:

int *p; int a=5;

cout<<*p; // value displayed is 910569528

In this code, the pointer ‘p’ hasn’t been assigned the address of ‘a’. ‘p’ will have some random memory location and reading the value at this location produces a garbage value. Programmers thus prefer to use:

int *p=NULL; int a=5; cout<<*p;

This code will generate an error when it is run in your computer because ‘p’ is pointing to the location 0x00000000.

7.) Potential hazards of using uninitialized pointers:

There are instances when a programmer declares a pointer and forgets to initialize it. Later in the code the programmer uses this pointer and this can lead to serious errors. Since the pointer has some unknown address value, when we dereference such a pointer we cannot predict what will be the value. A bigger problem might arise if you attempt to change the value stored at that address. For ex:

int *p; *p=5;

In this case, the value at an unknown location will get changed to 5. This particular memory location could actually be some other variable in your program. Thus indirectly you would have changed the value of another variable and it will become difficult to trace the problem.

You may be wondering why we need to tell the compiler as to what type of data a pointer is going to point to? A pointer just holds an address, so why do we need to specify the data type pointed to?

The problem will occur when you make use of the dereferencing operator to get the value stored at the address. If a pointer points to a character, then the compiler knows that when we dereference the pointer it should only read one byte. If the pointer points to a short int the compiler knows that it has to read 2 bytes and so on. If we didn’t specify what data type the pointer will point to, then the compiler has no idea as to how many bytes it should read when dereferenced. And if we never dereferenced a pointer then we’d never know what is stored at a particular memory address!

What’s the difference between: int *ptr;

and

int* ptr;

It is a matter of choice. Some programmers prefer the first one while you may frequently encounter the second type of declaration. The advantage of using the first method is that you are less likely to commit the mistake of declaring a pointer and an integer in one statement. Ex: if you want to declare to pointer ptr1 and ptr2, it is less likely to type

int *ptr, ptr2;

Use whichever method you are comfortable with.

In document C++ Basics to Advanced (Page 195-199)