Skip to content

Pointer Variable

Finding Address

Let's look back at the variable a we have before.

Variable
1
2
int /* data type */ a; /* name */
a = 123; /* value: may only be integer */

Now, we want to be able to retrieve the address of variable a. How can we do that? C provides an operator called the address operator using the & symbol ( the symbol is called the ampersand).

We can print the variables using the format specifier %p. This will print the address in hexadecimal1.

Address.c
1
2
3
4
int a = 123;
printf("a = %d\n", a);
printf("&a = %p\n", &a);
printf("&a = %d\n", &a); // Warning here

Try running the code in "ReplIt" tab above and you will see that address will be different each time you run it. This is actually intentional to secure against some type of security attacks. This technique is called address space layout randomization also called ASLR.

Of course, even without ASLR, the address is never guaranteed to be the same between two different runs of the same program. This is because the system will simply allocates any free memory currently available to the program. Depending on what other programs are running, that free memory might be different.

Declaring a Pointer

Syntax

<data type> *<pointer name>;

The magic symbol here is the star (i.e., *). Here, the <pointer name> is the name (i.e., identifier) of the pointer variable. The <data type> is the data type of the variable that this pointer may point to. A good practice is to name a pointer with a suffix _ptr or simply _p.

Integer Pointer Declaration
1
int *a_ptr;

Remember how we can declare multiple variables in a single line? We can also do the same for pointer variable. Unfortunately, this can quickly lead to confusion if you are not used to pointer.

First, we will show a simple unambiguous case of multiple declaration involving a single pointer variable.

Unambiguous Pointer Declaration
1
int a, *a_ptr;

Here we can see that variable a is an integer and a_ptr is a pointer to an integer. Now, what happen if we reverse the order and add a little twist to the spacing?

Confusing Pointer Declaration
1
int* a_ptr, a; // This will compile but can be confusing

Obviously, the type of a_ptr is a pointer to an integer. But what about the type of a? In this case, the type of a is still an integer. So, how do we declare multiple pointer variables in a single declaration? We will have to put the * for each of the name to make the variable into a pointer variable.

Multiple Pointer Declaration
1
int *a_ptr, *b_ptr; // Declaring two pointer variables

Good Practice

As a good practice, always put the * before the name instead of after the type. Although both are accepted, the latter may create confusion as our brain tend to group consecutive characters together.

Assigning Value to a Pointer

Like any other variable in C, the value of an uninitialised variable should be considered to be random value. We need to assign a value to the pointer variable to ensure that the pointer indeed points to a useful address such as the address of a variable and not some random memory location. Since we have seen that the address of a variable is randomised at the start of the program execution, you can see the benefit of using the & operator.

Unitialised Integer Pointer
1
2
3
int a = 123;
int *a_ptr; // uninitialised
a_ptr = &a; // points to variable a

We can also combine the declaration and initialisation similar to how we can initialise a variable during declaration.

Initialised Integer Pointer
1
2
int a = 123;
int *a_ptr = &a; // initialised to point to variable a

Box-and-Arrow Diagram

A simple graphical representation of a pointer is the box-and-arrow diagram. If we can look at the actual memory used by a program, we may see something like the table below. Note that we exclude the type since we are not currently interested in the type. We assume the code "Unitialised Integer Pointer" is being run and that the variable a is allocated the address ffbff7dc.

Address Name Value Comment
ffbff7dc a 123 Variable a at ffbff7dc with value 123
ffbff7ff a_ptr ffbff7dc Variable a_ptr at ffbff7ff with value ffbff7dc

Box Diagram

We can also draw the memory using boxes. However, as we do not really care about the actual value of the address (remember, the address is randomised anyway), we only care about which variable the pointer is pointing to.

Box-and-Arrow Diagram

This means that the diagram can be simplified further. In particular, the content of the box a_ptr can be anything. But to show that it is pointing to the box a, we simply draw a literal pointer using arrow.

Accessing Variable Through Pointer

Once we have created a pointer a_ptr that points to the variable a (as above), we now have two access points to the variable a. The first is the usual direct access using the variable name and the second is indirect access using the pointer variable a_ptr. Indirect access is done using the indirection operator (a.k.a. dereferencing operator) using the * symbol.

Deref.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int a = 123;
int *a_ptr = &a;

printf("a = %d\n", *a_ptr); // Indirect access
printf("a = %d\n", a);      // Direct access

*a_ptr = 456;               // Equivalent to a = 456;

printf("a = %d\n", *a_ptr); // Indirect access
printf("a = %d\n", a);      // Direct access

Star (*)

Note that the star symbol (*) has two meanings depending on the context of usage.

  1. Variable Declaration: Creates a pointer variable.
  2. Variable Usage: Accesses the variable pointer pointed to by the pointer variable (i.e., indirect access or dereferencing).

Note that the second usage is basically anywhere except variable declaration.

Common Mistake

What is wrong with the following code?

CommonMistake.c
1
2
3
int *n;
*n = 123;
printf("%d\n", *n);

Unfortunately, the "ReplIt" tab does not show the error because it is compiled with Clang that is doing a smart initialisation. Try the following:

  1. Click the "ReplIt" tab, and the the "Shell" tab.
  2. Compile with GCC using gcc main.c
  3. Execute the code using ./a.out

Segmentation Fault

You should see Segmentation fault (core dumped). This is caused because the pointer variable n is not pointing to any valid variable! In fact, if you draw the box-and-arrow diagram, you will not know where to connect the arrow to. If you run this on your own computer, remove the file core from your directory as it takes up a lot of space.


  1. You can also try to print it using %d, but the compiler will give you a warning.