DEV Community

Cover image for What Are You Pointing At???
Dave Mcsavvy
Dave Mcsavvy

Posted on

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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

Top comments (1)

Collapse
 
pauljlucas profile image
Paul J. Lucas

The * neither reads nor writes the contents of a memory address. I can do:

(void)*x;
Enter fullscreen mode Exit fullscreen mode

* accesses the value of a memory address. What you do with that value is up to you.