C Pointers Explained

Yet again.


10 Mar 2018 View Comments
#pointer #reference #memory #computer #programming

If you are a software developer, you probably have been taught numerous times about the pointers in the college. Well, I have and each time I get the satisfaction of “hey, I know how pointers work!”. The funny thing is each time I come back to use it again, I am back to square one. The truth is it still confuses the hell out of me.

At the beginning of my career, I ended up programming in Perl about 10 years. As I am being soaked into Perl’s syntaxes and mechanisms, the concept of pointers in C grew to be even more confusing. There is the concept of the “references” in Perl which behaves very similar to the C pointers (references). However, at the end of the day, Perl’s references and C pointers are not exactly the same though.

Pointers

The concept of pointers is really simple. You literally just have to remember this:

A pointer in C/C++ points to a memory location. That's pretty much it.

As usual, we can start with a very simple example in C:

int foo = 1;
int* pFoo = &foo;

What is happening above? The first line sets an integer variable called foo to the value 1. Then the second line creates the integer pointer called pFoo which holds the memory location of foo by calling &foo. When you print out the content of the pointer, pFoo in human-visible form, it would be something like:

pFoo: 0x7ffd01d82d54

As you see pFoo contains the memory location of the variable foo. How do we use the pointers then? Let’s add the third line to the example above.

int foo = 1;
int* pFoo = &foo;
*pFoo = 15;

This 3rd line might confuse a couple of people here because this could be appearing as setting 15 to the memory location. That is obviously not the case. *pFoo means to follow the memory address and deal with the memory it points to. We should not be confused ourselves with, *. This would be used for initializing a pointer. It's probably easier to understand the above example more straightforward if I draw out the example above, like below:

   :
   :        
|-----|
0x5100|   1  |   foo is an integer with value 1
|-----|
0x5104| 5100 |   pFoo points to memory location: 5100
|-----|
0x5108|   ?  |   others (who knows whats in here)
|-----|
   :
   :

We can see that the pFoo is basically pointing to the foo variable (residing in memory location 0x5100). This example is really all there are for C pointers.

However, we can make things more interesting to the problem by adding a pointer to a pointer. Let’s take a look at the new fourth line below:

int foo = 1;
int* pFoo = &foo;
*pFoo = 15;
int** ppFoo = &pFoo;

So ppFoo is pointing to the memory location of pFoo which is a pointer to a variable pFoo. Now if you wanted to change the value of foo using ppFoo, you can simply call: **pFoo = 15;, then the pointers will follow to the memory location it’s pointing at and eventually update the value of foo.

There are even more complexities you can add to the pointer flavour such as **ppFoo++. Well, what does **ppFoo++ mean? ++ binds tighter than *, so this is equivalent to: *( *( ppFoo++ ) ). So you essentially broke your pointer to point at some random spot (probably nowhere, null). Your compiler will most likely bark at you if you try to do this seemingly unrealistic thing. What about this? ++**ppFoo. This is nothing but fetching what’s contained in ppFoo and increment 1 to it. You will get the similar issue as the previous if you do this though, **++ppFoo.

So why do we use pointers? Well, there are a couple of reasons:

  1. In order to call-by-reference to a function, a pointer is used.
  2. Run faster because you can avoid creating duplicated data over again (Performance gain)
  3. It also saves memory space because you are avoiding creation of redundant duplicated data.

There are other reasons to use pointers, but above 3 are biggest ones which I can think of.

References

To complete the topic of the pointers, references naturally follow for a discussion. Specifically, references are not available in C. The reference syntax is introduced in C++. However, references are worth a mention here as pointers and references are quite similar and go hand in hand. To place a definition of a reference:

A reference variable is essentially an alias which is another name for an already existing variable.

References work just like pointers with some syntactic sugar. int& rFoo and int* pFoo are essentially the same things, but you don’t have to dereference the reference. The reference basically acts as an ‘alias’ to a variable meaning unlike pointers, you do not always need the * in front of it to fetch/set the data.

We should remember that the references are required to always be pointing to a valid destination though. You cannot have an empty reference. Also, with a reference, you cannot change it to refer some other variable once it had been initialized. You can only choose what that reference would point to upon initializing it.

Share this post

Me

I am a passionate software developer working in Downtown, Vancouver. I strongly believe in art of algorithms and together with it to write clean and efficient software to build awesome products. If you would like to connect with me, choose one from below options :) You can also send me an email at