What Are You Pointing At???

What Are You Pointing At???

If you really want to kick ass in C, you need to understand how C handles memory


The C language gives you a lot more control over how your program uses the computer memory, let's go behind the scenes and see what happens every time you assign, modify or use a variable.

C code inludes pointers

To best understand pointers, go slowly

Pointers are one of the most fundamental things to understand in the C programming language. So what’s a pointer? A pointer is just the address of a piece of data in memory.

Pointers are useful for the following reasons.

  1. Instead of passing around a whole copy of the data, you can just pass a pointer to the original data.

  2. You might want two pieces of code to work on the same piece of data rather than a separate copy.

To illustrate, look at the following code

Example 1 The program starts with n as 100, so if n is increased by 1 it would now be 101. At least it would be if the code works

Look at the code carefully. Do you think it will work? Why? Why not?


> gcc addone.c -o addone
> ./addone
the value of n is 100
the value of n is now 100

Hmmm, why didn't our function work?


C sends arguments as values

The code broke because of the way C calls functions.

  1. Initially the main() function has a local variable called n that had value 100

  2. When the program calls the add_one() function, it copies the value of n from main() to add_one(). This means that even though they look like the same variables, they are not because when you call a function, you don't send the variable as an argument, just it's value.

  3. When the add_one() function changes the value of n, the function is just changing its local copy. This means when the computer returns to the main() function, the n variable still has its original value of 100

But if that's how C calls functions, how can you ever write a function that updates a value? It's easy if you use pointers...


Using memory pointers

1. Get the address of a variable

You can find where a variable is stored in memory using the & operator.

int x = 4;
printf("x lives at %p\n", &x);

But one you've got the address of a variable, you may want to store it somewhere. To do that, you will need a pointer variable. A pointer variable is just a variable that stores a memory address. When you declare a pointer variable, you need to say what kind of data is stores at the address it will point to.

int *address_of_x = &x;
printf("x lives at %p\n", address_of_x);

2. Read the contents of an address

When you have a memory address, you will want to read the data that's stored there. You do that with the * operator

int value_stored = *address_of_x;

The * and & operators are opposites. The & operator takes a piece of data and tells you where it's stores. The * operator takes an address and tells you what's stored there.

Because pointers are sometimes called referrences, the * operator is said to dereference a pointer.

3. Change the contents of an address

If you have a pointer variable and you want to change the data at the address where the variable's pointing to, you can just use the * operator again. But this time you need to use it on the left side of an assignment

*address_of_x = 99;

OK, now that you know how to read and write the contents of a memory location(pointer), it's time for you to fix the add_one() function.

Example 2


Solution

Example 3

> gcc addone.c -o addone
> ./addone
the value of n is 100
the value of n is now 101

The code works.

Because the function takes a pointer argument, it’s able to update the original n variable. That means that you now know how to create functions that not only return values, but can also update any memory locations that are passed to them.


BULLET POINTS

  • Variable are allocated storage in memory
  • Pointers are just variables that store memory addresses
  • The & operator finds the address of a variable
  • The * operator can read the contents of a memory address
  • The * operator can also set the contents of a memory address