Pointers and memory
Most people think of pointers as an advanced topic. And honestly, the more you think of them as advanced, the more you'll fear them and the less you'll understand such a simple thing. You are not an idiot, let me prove that for you.
When you declare a variable in your program, you know that this variable occupies a place in your memory (RAM), right? Because when you access it, when you change its value, it must exist somewhere!
And this somewhere is the variable's address in memory.
Now, when you buy your RAM, it's nowadays sold in GB (Giga Bytes), that is how many bytes are available to be used by your program and its variables. And you guess, that the string "Hello, world" doesn't occupy the same amount of RAM as a simple integer.
For example, the variable
i can occupy 4 bytes of your RAM starting from the
100th byte to the 103th, and the string
"Hello world" can occupy more ram
starting from the 105th byte to the 116th byte.
The first byte's number of the space occupied by the variable is called its address.
And we use the
& operator to find out the address of a given variable.
You see? Each variable has its own address, and you can guess that the addresses of variables depend on the amount of RAM occupied by some other variables.
The variables that can store other variables' addresses are called pointers to these variables.
How to declare a pointer?
For any given type
T, there is an associated type
*T for pointers
to variables of type
How to access the value of a pointed-to variable?
Ptr is a pointer to
Ptr == &Var. And
*Ptr == Var.
In other words: you precede a variable with the
& operator to obtain its
address (a pointer to it), and you precede a pointer by the
* operator to
obtain the value of the variable it points to. And this is called:
&is called the address operator.
*is called the dereferencing operator.
And that is all! Pointers are variables that store other variables addresses, and
if a variable is of type
int, its pointer will be of type
*int, if it is
float32, its pointer is of type
*float32 and so on...
Why do we need pointers?
Since we can access variables, assign values to them using only their names, one might wonder why and how pointers are useful. This is a very legitimate question, and you'll see the answer is quite simple.
Suppose that your program as it runs needs some to store some results in some new variables not already declared. How would it do that? You'll say: I'll prepare some variables just in case. But wait, what if the number of new variables differs on each execution of your program?
The answer is runtime allocation: your program will allocate some memory to store some data while it is running.
Go has a built-in allocation function called
new which allocates exactly
the amount of memory required to store a variable of a given type, and after
it allocates the memory, it returns a pointer.
You use it like this:
Type is the type of the variable
you want to use.
Here's an example to explain the
Another good reason, that we will see when we will study functions is that passing parameters by reference can be useful in many cases. But that's a story for another day. Until then, I hope that you have assimilated the notion of pointers, but don't worry, we will work with them gradually in the next chapters, and you'll see that the fear some people have about them is unjustified.