How do pointers in C++ work, and why are they different from references?

193 views
0

Edit: Perhaps I mean “how” are they different from references, not why.

In: Technology

Probably the main thing about a pointer is that its value – as in, the location in memory being pointed at – can be directly manipulated, whether that is warranted or not. A user can write `(pointer+1)` to point at the memory slightly to the right of what it was originally pointing at. It’s treated as the next item in an array as though the pointer was to an array (either the first item, or really any item). Indeed, `*(pointer+x)` is nigh-identical to `pointer[x]`. This is potentially very useful, but also potentially very dangerous as there are not any real ways to validate if the memory is fair game. Not all invalid memory reads/writes crash a program (or a crash may be delayed). Of course, it could also be the NULL pointer indicating it doesn’t actually exist, giving you the option to point to nothing.

By contrast, a reference is sorta like a pointer where the compiler takes care of managing where it’s pointing for you. There is no ambiguity as to whether the variable pointed at is an array, or even if the object exists. A variable passed by reference must exist and you cannot insert a NULL value instead.

So like so many things in life, a pointer is potentially more powerful and expressive, but also more dangerous and there is no built-in safety net.

This is really, really tough to distill down to ELI5. In particular, the difference between a pointer and a reference takes some pretty out-there thought. But let’s go.

Think about a house. A house is like a variable. It is where it is, it is what it is. If I say I’m giving you that house, then you get that house. If we both want that house, one of us has to build another house just like it so there are 2 houses. This is how “variables” work.

That house can have an address. Let’s say it’s 123 Main Street. Every house has an address, that’s how we tell people which house we mean. This isn’t quite pointers yet, but it’s important to know that houses have addresses, and variables have addresses. You can’t really *change* the house’s address, though. (Nitpicky aside: your city might rename or renumber the street, but this is really rare, so we’re going to pretend it doesn’t happen, OK?) If you move, the house at 123 Main Street is still the house at 123 Main Street. You’re in a different house with a different address now. This reflects that, with variables, knowing that they have an address doesn’t really help us do much.

We call addresses, when used in this way, “indirection”. That is to say, once I have pieces of paper and addresses, I can talk about a house without having to be close enough to point. If I give you the address and say, “Here’s the house I mean”, you know the paper isn’t a house. You understand it is instructions for how to find a specific house. Indirection.

Now. Imagine I write “123 Main Street” on a piece of paper. NOW I have a pointer. I can give you the piece of paper, and you can find the house. The paper “points to” the house. When you get there, maybe you want to give someone else directions. You can erase what I wrote and write a different address on the paper. So that piece of paper can point at any house in the world! All you have to do is write a new address on it.

So. References. Maybe I gave you that piece of paper to give to someone else. And maybe I wanted them to see “123 Main Street” and I’m mad that you wrote another address on it. So next time, I give you a stone tablet into which I carved “123 Main Street”. Now you can’t erase the address and replace it with a different one. (Not easily, at least.) This is how references are different from pointers. They still provide indirection, but it’s a kind that can’t be changed so easily.

There are some other subtle differences. For example, technically a piece of paper can refer to ANYTHING. Suppose I have 10 pieces of paper with 10 different house addresses on them. Now suppose I write the numbers 1-10 on them. And I give you a post-it that says “Address number 3”. So you pick up the other paper that has “3” on it, and go to the house at that address. My post-it has the address of an address on it now! This is a pointer-to-a-pointer, or “a second level of indirection”. You cannot do this with references.

A pointer is a variable that holds a memory address.

Your business card is a pointer, it tells me your address. Knowing that doesn’t tell me who’s in your house, I just know where to look if I want to know who’s there. Deferencing is like taking my knowledge of your address and using to drive to your house, go inside, and see who’s there.

A reference is basically an always dereferenced pointer. You’re always looking through the reference at the value of the referenced variable.