Skip to main content
Go Language Fundamentals for Beginners to Advanced
CHAPTER 13 Beginner

Pointers in Go

Updated: May 17, 2026
5 min read

# CHAPTER 13

Pointers in Go

1. Introduction

If you have a 500MB image loaded in memory and you want a function to process it, handing the function a *copy* of the 500MB image will crash your RAM. Instead, you give the function a piece of paper with the address of where the image is stored. This piece of paper is a Pointer. Pointers are the secret to Go's incredible execution speed and memory efficiency.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand memory addresses.
  • Use the & (Address of) operator.
  • Use the * (Dereference) operator.
  • Understand Pass-by-Value vs Pass-by-Reference.
  • Avoid common pointer mistakes.

3. Memory Addresses and the & Operator

Every variable you create lives in a specific slot in your computer's RAM. Every slot has a unique hexadecimal address (e.g., 0xc000018030). You can find the address of any variable using the & (Ampersand) operator.
go
123456789
package main
import "fmt"

func main() {
    age := 25
    
    fmt.Println("Value of age:", age) // Prints 25
    fmt.Println("Memory address of age:", &age) // Prints 0xc000018030
}

4. What is a Pointer?

A Pointer is simply a variable that stores a memory address instead of a standard value. You declare a pointer by putting an * (Asterisk) in front of the data type.
go
12345678
func main() {
    age := 25
    
    // ptr is a pointer to an integer
    var ptr *int = &age 
    
    fmt.Println("Pointer stores:", ptr) // Prints 0xc000018030
}

5. Dereferencing (The * Operator)

If a pointer holds an address, how do we get the actual data living at that address? We use the * operator *in front of the pointer variable*. This is called Dereferencing.
go
12345678910111213
func main() {
    age := 25
    ptr := &age 
    
    // Read the value at the address
    fmt.Println("Value at ptr:", *ptr) // Prints 25
    
    // Change the value at the address!
    *ptr = 99 
    
    // age was changed directly!
    fmt.Println("New age:", age) // Prints 99
}

6. Pass by Value vs Pass by Reference

By default, when you pass a variable to a function in Go, it passes a copy of the variable (Pass by Value). If the function changes it, the original variable is unaffected.

If you want the function to modify the original variable, you must pass a Pointer (Pass by Reference).

Pass by Value (Does not change original):

go
123456789
func doubleValue(num int) {
    num = num * 2 // Only changes the local copy
}

func main() {
    x := 10
    doubleValue(x)
    fmt.Println(x) // Still prints 10!
}

Pass by Reference (Changes original):

go
12345678910
// Expects a memory address (*int)
func doublePointer(num *int) {
    *num = *num * 2 // Modifies the data at the address
}

func main() {
    x := 10
    doublePointer(&x) // Give it the address!
    fmt.Println(x) // Prints 20!
}

7. Pointers with Slices and Maps

You rarely need to use pointers with Slices and Maps. Why? Because under the hood, Slices and Maps are *already* pointers! When you pass a slice to a function, you are inherently passing a reference to the hidden underlying array.

8. Common Mistakes

  • Nil Pointers: If you declare var ptr *int but do not assign it an address, it is nil. If you try to dereference a nil pointer (*ptr = 5), the program will instantly crash (Panic).
  • Pointer Arithmetic: In C/C++, you can do ptr++ to jump to the next memory slot. Go strictly forbids pointer arithmetic to prevent massive security vulnerabilities and memory corruption.

9. Best Practices

  • Use pointers when you need a function to modify the original data.
  • Use pointers when passing massive Structs (which we will learn next) to prevent the CPU from slowly copying huge amounts of data.
  • Do NOT use pointers for basic types (int, bool) unless absolutely necessary. Passing copies of small variables is actually faster than managing pointers.

10. Exercises

  1. 1. Write a function swap(a *int, b *int) that swaps the values of the two variables.
  1. 2. In main(), create x := 1 and y := 2. Print them, call swap(&x, &y), and print them again.

11. MCQs with Answers & Explanations

Question 1

What is a Pointer?

Question 2

Which operator is used to find the memory address of a variable?

# Answer: b) &.
Question 3

Which operator is used to read or modify the data located at a specific memory address?

Q4. By default, how does Go pass variables into functions? a) Pass by Reference b) Pass by Value (It makes a copy) Answer: b) Pass by Value.

Q5. How do you pass a variable by reference so the function can modify the original? a) Pass the variable normally b) Pass the memory address using & and accept it as a pointer *type Answer: b) Pass the memory address using & and accept it as a pointer.

Q6. Does Go allow Pointer Arithmetic (e.g., ptr++)? a) Yes b) No Answer: b) No. *Explanation: This prevents memory corruption and keeps Go safe.*

Question 7

What happens if you try to dereference a nil pointer?

Q8. Should you use pointers for passing Slices and Maps to functions? a) Yes, always b) No, they are already reference types under the hood Answer: b) No, they are already reference types under the hood.
Question 9

If x := 10, what does fmt.Println(&x) print?

Q10. What is the primary performance benefit of using pointers? a) It encrypts the data b) It avoids the CPU overhead of copying large amounts of data when passing variables to functions Answer: b) It avoids the CPU overhead of copying large amounts of data.

12. Interview Preparation

Interview Questions:
  1. 1. What is the difference between & and * in Go?
  1. 2. Why does Go support pointers but forbid pointer arithmetic? (Answer: To achieve C-like performance without the notorious memory safety vulnerabilities of C/C++).

13. Summary

Pointers are the gateway to writing highly performant code. By passing memory addresses (&) instead of copying data, your applications run significantly faster and consume less RAM. While they can seem intimidating, remembering that & means "Address of" and * means "Value at" makes them easy to master.

14. Next Chapter Recommendation

Passing around individual integers with pointers is useful, but real applications deal with complex objects like Users and Products. In Chapter 14: Structs in Go, we will learn how to create custom data types and build the foundation of Go's unique take on Object-Oriented Programming.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·