Pointers and References
Memory
- In the context of this tutorial, memory is simply a place/register/space in our RAM where variables are stored.
Pointers
Introduction
- A pointer is just a Number (integer) that holds memory address of another variable.
- Size of this number/integer is not fixed. It depends upon OS, CPU architecture etc.
- For example, 4 bytes for 32 bit system and 8 bytes for 64 bit system.
- Adding
&
in front of a vaiable name gives the address in memory where that variable is stored in. - In other words, adding
&
before variable name gives pointer to that variable.
1 | #include <iostream> |
Output
- Here,
0x7fffa8b8fc5b
is the memory address where variablex
is kept at and similar for variablesy
andz
. - We can also define a pointer variable to store this address of
x
: Output - Here, pointer variable
ptr
is defined asvoid* ptr
. - But what does
void*
term actually mean? Well, the following section explain about this is detail.
Type of Pointer
- Can a pointer have type?
- In above example pointers to
bool x
,int y
anddouble z
all looks similar. - Indeed, that are same. Value of each of them is 8 byte integer (for 64 bit system).
- No matter which variable is it pointing, its value is always 8 byte integer.
- One difference we can notice is, the increment in memory address from
x to z
is not same. - There is increment of 1 between
x
andy
. And increment of 4 betweeny
andz
. - This is because
x
is abool
variable which takes 1 bytes of space andy
isint
variable which takes 4 bytes of space in memory. - Basically,
&x
is the memory address of first byte wherex
is stored. And,&y
is the memory address of first byte wherey
is stored. Similar for&z
.
Note: Variables may not be stored consequiteley in the memory
- So, the pointer variable which is pointing to the first byte of integer can be referred to as integer pointer. Similar for other variables.
void*
used in above example is pointer without any specific type.- Lets clear this once again. From the perspective of a CPU, all pointers are treated the same. We just assign the different types to pointers such as
bool*
,int*
,float*
etc for the ease of use. One advantage is to know which datatype is the given pointer variable pointing to. - Another advantage is in Pointer Arthematic. Which is explained in following sections.
- Type of pointer also comes in handy when we assign specific value to the variable pointed by that pointer. Output
- Here, we were able to assign value 10 to
int* ptr
because we told compiler thatptr
holds the variable of typeint
.:w
Pointer Arthematic
- We have
int* ptr
. What might happen if we try to increment it (i.e.ptr++
)? - Lets Try: Output
- How about using
bool*
Output - Noticed the difference between incrementing
int*
andbool*
? - Pointer values are incremented by 4 for
int*
and by 1 forbool*
- That is obviously because size of
int
is 4 bytes andbool
is 1 byte. - This type of increment was possible because we specified a TYPE to the pointer.
Accessing uninitialized pointers
- Rule is: Never try to read or write the address pointed by uninitialized pointers
- Uninitialized pointer variabes will hold random value which points to random section of memory.
- And if that section is not readable or writable, the program crashes !
1 | int* ptr; // Here ptr is uninitialized |
Output
NULL Pointer
- Can be null (TODO)
More on Pointers
- Pointer can hold memory address of variable stored in Stack or in Heap. See more about this here.
References
Introduction
- References are like a disguised version of Pointers.
- References are like the nickname/alias given to a variable’s Pointer.
- References themselves are not new variables. They don’t occupy space in the memory. They are just there in our source code to make our work easier.
- They just “refer” to the existing variable. Output
- Here, we have created a reference to the variable
x
.
Note: &
used here has different meaning than that of &
used as address of operator !
- And now we can use this term
reference_to_x
as if it wasx
. - But what’s fun in that? Why do we even need
reference_to_x
when we can directly usex
?
Pass by Value vs Pointer vs Reference
Pass by Value
Output
- Here,
add_one
function copies the int value passed into it and increments the duplicate value. - So,
x
remains unchanged.
Pass by Pointer
Output
- Here, the memory address of
x
is passed. add_value
duplcates the memory address passed into it, but it still points to the same valuex
- Then inreasing
*val
increases the value inx
too.
Pass by Reference
Output
- This code looks exactly similar to that in Pass by Value, except one little
&
afterint
inadd_one
function. - This behaves exactly as Pass by Pointer but look much pleasing to read and write.
- It’s just syntatic sugar !!
Criteria of using References (TODO)
- Must be initialized
- Cannot be reassigned!