Golang, What the Hell is a Pointer?

Demystifying the Golang Pointer Once and for All

Ciaran Mcveigh
5 min readOct 30, 2019

So what is a pointer in Golang? It’s a common question to those new to Go and one that should be explained fully to give the reader a solid foundation upon which they can build their understanding of the Go language. To understand the Go pointer we first must start with a quick overview of how computer memory works and how its related to your Golang programs.

A Brief Introduction To Computer Memory

Computer memory, RAM, can be thought of as a series of boxes which each have an associated address and value. The boxes are labelled with a unique number, which increments sequentially; this is the address of the cell, its memory location. Each cell holds a single value. The diagram below may help crystallise this idea in your head. Note the empty cells represent cells where no value has been allocated.

A representation of RAM

The above diagram shows four memory addresses 0000 to 0003 three of which have been filled with a value. You can imagine these values being a username (Jimmy) at 0003, a password at 0001 and an account balance at 0002. If you know the memory address of a cell, you can go to that cell and read its contents or you can place a value in that cell; replacing anything that was in there previously. With access to these values our programs can then manipulate them to achieve some desired result.

Computer Memory in Golang

So how does this relate to Golang pointers, take a look at the following code.

A very simple Golang program that creates a variable called “age” and assigns it a value of 3. We then do two simple print statements one on “age” which represents the value of the variable “age” and one on “&age” which represents the memory address of the variable age. You can run the code here https://play.golang.org/p/ubkMp5bmjMQ. The output I get is,

age Value: 3
age Memory Address: 0x414020

Now while I represented memory address values as decimal numbers here it is represented as a hexadecimal number. Don’t be confused its still just a number, 0x414020 in hexadecimal is actually equal to 4276256 in decimal. Read more about hexadecimal numbers here. So this is how our RAM looks when running this code.

A Representation of RAM for our Simple Go Program

Here we can see that the memory address 0x414020 holds a value of 3. It is also clear that each memory address is unique, if we look at the last number in the addresses they go 0, 1, 2, 3. Finally we can see that within our program “age” points to the associated value while “&age” points to the memory address where that associated value is stored.

Golang Operators

Ok now we’re starting to get a rough picture of how values are stored in memory in our Golang program. Above we saw the use the &age, this is an operator in Golang. We have the ampersand operator &age and the star operator *age. The & operator gives us the memory address of the variable it is used with while the * operator when used with a memory address will return the value at that memory address. Again a simple example may help clarify.

The code above should look very familiar, all we’ve really added is one new value starOperatorAge and some additional print statements that print out the value of each variable and its type. Run it for yourself here https://play.golang.org/p/eC8d6yc2s7x. The output is shown below.

age Value: 3
age Type: int

age Memory Address: 0x414020
ampersandOperatorAge Type: *int

age Value at Memory Address: 3
starOperatorAge Type: int

Looking at the output the values make sense based on what we know about operators but what about the types. Age is of type int as is starOperatorAge but ampersandOperatorAge is of some strange type *int. *int means of type “integer POINTER” ie a memory address with an int stored as its value. If it were *string it would mean of type “string POINTER” ie a memory address with an string stored as its value. So in Golang when you hear someone talk about a pointer the first key point is to understand is that a pointer is simply the memory address of where some value is stored.

Ok so we finally know what a pointer is but hold on, this is also the point where people can get very confused. Why? Because * means two different things depending on the context. When * is used within a type declaration as I have show with *int it means a pointer to some type (in this case an integer), however when * is used as an operator as I showed with *ampersandOperatorAge it is used on memory addresses (which we just found out are referred to as pointers in Golang) to get the value at that address. Im going to write this out again to really hammer home this point.

Star (*) Type Declaration Context ie *int- Means a pointer to some type (memory address with value of type X)--------------------------------------------------------------------Star (*) Operator Context ie *ampersandOperatorAge- Means get the value at some memory address

Now we understand the types an important note to make is that the * operator can only be used on memory addresses AKA pointers AKA variables of *someType. This means if I were to try to add the line starOperatorAge := *age I would get an error as the * operator can not be used on a variable of type int. Hopefully you are starting to see the pieces fit together.

We’re almost done, we should now have a good grasp of what a Golang pointer is and how it relates to a variables value and its memory address. In Part 2 (coming soon) we will explore why pointers are needed in Goalng as well as their common uses and gotchas.

Hopefully this has helped you gain a better understanding of pointers in Go. As always any feedback is welcome and please let me know if I’ve made any mistakes.

--

--