A pointer is nothing but a variable ,
but the speciality of this variable is that it stores the address
location of another variable. So, it means that we can have a normal
variable which is located at some particular address in the memory,
and then we can also have another variable which can actually let us
know the address where the previous variable is stored.
Let us understand it in a more clear
way with the help of an example:-
We can actually alter the value of a variable by altering the value while dereferencing the pointer.
What happens if we try to dereference some pointer which has been initialized to be NULL?
Here, we have defined 5 variables in
total.4 of them are normal integer variables holding some values and
the 5th one is a pointer to an integer.
<< When you declare a pointer as
int *p, you read it as p
is a pointer to an integer.>>
Then, before every
printf() statement, we are assigning the value of p to each and every
integer variable. Let's see how the output follows :-
What
we observe here is that p is pointing to a different location each
and every time.This is so because we are making the pointer variable
*p point
to a different variable each and every time.
The above code and
output have a lot to say. Let us discuss them one by one.
- The memory address values are in Hexadecimal format. It's because we have used the format specifier as %p .
- The difference between any 2 consecutive address values is 4 Bytes. What does this mean? Is it because the integer size is 4 bytes??--Absolutely right. Each integer value occupies 4 Bytes of space in memory, hence the next variable's address is 4 Bytes after it.---
- Size of a pointer to an integer is 4 Bytes.
- What if the variables used were char type, which are only 1 Bytes wide?--Let's see it.
And then the
output is:-
Is everything
alright?? The difference between address locations of 2 consecutive
variables is only 1 Byte, as expected. But wait !!!
Why is the size of
p still 4??
Well, The answer
is the size of a pointer is always fixed for a particular
architecture, no matter whether that is a pointer to an integer , a
pointer to a character ,a pointer to a float variable or a pointer to
a double variable.
Since the above
code has been executed on an x86-based 32-bit machine, the size of a
pointer is 4 Bytes.
On a 64-bit
machine, the size of a pointer will be 8 Bytes. Similarly, on a
16-bit machine, the size of a pointer will be 2 Bytes.
<<However,
the above statement is not strictly true, and a little bit of Googling will probably make you aware of the fact.>>
Referencing and dereferencing of a
pointer -
.
.
.
void func()
{
int a=10,*p,b;
p=&a; //p is
referencing a with the help of & operator
//Since 'p' has
already referenced 'a', we can access the value stored at the address
location pointed to by 'p' by dereferencing it.
printf (“ value
at the address pointed to by p is \n”,*p); //Here, p is being dereferenced with the //help of * operator
}
.
.
And then the
output of the printf() statement will show us the value 10, which we
got by dereferencing the pointer 'p'.
<< & is
known as the reference operator, and is used to access the “address
of” the variable it is being used with.
* is known as the
dereference operator , and is used to access the “value pointed by”
the pointer it is being used with.>>
We can actually alter the value of a variable by altering the value while dereferencing the pointer.
For example, in
the above piece of code, if we do the following :-
.
.
*p=*p+5;
printf(“ value
of a is %d\n”,a); //a becomes 15
.
.
.
printf() will
display the output of 'a' as 15, because the value has been changed
by dereferencing the pointer to the variable 'a'.
What happens if we try to dereference some pointer which has just been declared but not initialized?
What happens if we try to dereference some pointer which has just been declared but not initialized?
What happens if we try to dereference some pointer which has been initialized to be NULL?
Let's see both
these scenarios with a small piece of code.
Here, 'p' is a
pointer which is un-initialized,which means that this pointer may
point to any random location containing some garbage value or it may
be an invalid location at all.
'q' is a pointer
initialized with NULL value. This surely contains no valid location
since it has been initialized as NULL.
As seen in the
output, p is pointing to some unknown location containing some
unknown value.
q is not
pointing to any location. So, it's logically an act of stupidity to
dereference this pointer ( though we can do it here and we usually
keep doing it throughout life by mistake ;) ).
GCC throws the
exception as “Segmentation fault” in this case.
In case of
dereferencing p, GCC may throw “Segmentation fault” error too. It
just depends on what value is present on that randomly assigned
location. If nothing is present, then “Segmentation fault” will
definitely appear .
One more thing
that may seem surprising to some people is that on executing the code
for subsequent number of times, the memory address location changes.
Why does this happen?
For those who have
this query , they may tend to understand that the address is that of
the Physical memory, then why should it change again and again??
Shouldn't it remain static?
The answer is that
this address is not the Physical address(i.e., the RAM address), this
is rather known as Virtual address. Each time you execute the binary
file, you are actually starting a process, and each process has its
own virtual address space which is translated from the Physical
address space with the help of an MMU (memory management unit) in an
OS-based system.
So, for every
execution of the same code, the virtual address changes because you
actually start a new process each time.
We will discuss
memory management along with the address translation from Physical to
Virtual in more detail in the OS section.




No comments:
Post a Comment