Bird
Raised Fist0
Goprogramming~15 mins

Pointer declaration in Go - Deep Dive

Choose your learning style10 modes available
Overview - Pointer declaration
What is it?
A pointer declaration in Go is a way to create a variable that stores the memory address of another variable. Instead of holding a direct value, a pointer holds the location where the value is stored. This allows programs to access and modify data efficiently by referring to its address. Pointers are declared using the * symbol before the type.
Why it matters
Pointers exist to let programs work with data without copying it, saving memory and time. Without pointers, every time you pass data around, the program would make full copies, which can be slow and wasteful. Pointers also enable powerful programming techniques like sharing data between functions and building complex data structures like linked lists.
Where it fits
Before learning pointer declaration, you should understand basic variables and types in Go. After mastering pointers, you can learn about pointer arithmetic, references, and advanced data structures that rely on pointers.
Mental Model
Core Idea
A pointer is a variable that holds the address of another variable, letting you access or change that variable indirectly.
Think of it like...
Think of a pointer like a house address written on a piece of paper. The paper itself doesn't hold the furniture or people inside the house, but it tells you exactly where to find them.
Variable x stores value 42
Pointer p stores address of x

  +-------+       +-------+
  |   x   |       |   p   |
  |  42   |       | 0x123 |
  +-------+       +-------+
      ^               |
      |               v
    memory          points to
    0x123           x's location
Build-Up - 7 Steps
1
FoundationUnderstanding basic variables
🤔
Concept: Learn what variables are and how they store values in memory.
In Go, a variable is a named storage that holds a value of a specific type. For example, var x int = 10 creates an integer variable x holding the value 10. Variables have memory addresses where their values are stored.
Result
You can store and retrieve values using variables.
Knowing variables and their memory storage is essential before understanding pointers, which deal with these memory addresses.
2
FoundationMemory addresses and the & operator
🤔
Concept: Learn how to find the address of a variable using the & operator.
The & operator in Go returns the memory address of a variable. For example, &x gives the address where x is stored. This address is a unique location in the computer's memory.
Result
You can get the address of any variable using &.
Understanding how to get a variable's address is the first step to working with pointers.
3
IntermediateDeclaring a pointer variable
🤔Before reading on: do you think a pointer variable holds a value or an address? Commit to your answer.
Concept: Learn how to declare a pointer variable that stores the address of another variable.
In Go, you declare a pointer by placing * before the type. For example, var p *int declares p as a pointer to an int. You can assign it the address of an int variable like p = &x.
Result
Pointer p holds the memory address of x, not the value 10 itself.
Knowing how to declare pointers lets you create variables that refer to other variables indirectly.
4
IntermediateDereferencing pointers with * operator
🤔Before reading on: do you think *p gives the address stored in p or the value at that address? Commit to your answer.
Concept: Learn how to access or change the value a pointer points to by dereferencing it.
Using * before a pointer variable accesses the value at the stored address. For example, *p gives the value of x if p points to x. You can also assign *p = 20 to change x's value through p.
Result
Dereferencing lets you read or modify the original variable via its pointer.
Understanding dereferencing is key to using pointers effectively to manipulate data indirectly.
5
IntermediatePointer zero value and nil
🤔
Concept: Learn about the default value of pointers and the nil pointer.
A pointer that is not assigned an address has the zero value nil, meaning it points to nothing. Using a nil pointer causes runtime errors if dereferenced. Always check if a pointer is nil before using it.
Result
You avoid crashes by handling nil pointers safely.
Knowing about nil pointers helps prevent common bugs and crashes in programs.
6
AdvancedPointers and function parameters
🤔Before reading on: do you think passing a pointer to a function copies the data or shares the original? Commit to your answer.
Concept: Learn how pointers allow functions to modify variables outside their scope.
When you pass a pointer to a function, the function receives the address, not a copy of the value. This means the function can change the original variable by dereferencing the pointer.
Result
Functions can modify variables directly, enabling efficient data updates.
Understanding this prevents confusion about why some function calls change variables and others don't.
7
ExpertPointer internals and memory safety
🤔Before reading on: do you think Go allows pointer arithmetic like C? Commit to your answer.
Concept: Learn how Go manages pointers internally and enforces safety by disallowing pointer arithmetic.
Go pointers store memory addresses but do not support arithmetic (like adding numbers to pointers). This design prevents unsafe memory access and bugs common in languages like C. The Go runtime also tracks pointers for garbage collection.
Result
Go programs are safer and less prone to memory errors while still using pointers.
Knowing Go's pointer safety design helps write robust programs and understand language tradeoffs.
Under the Hood
Pointers in Go are variables that store memory addresses. When you declare a pointer, the program allocates space to hold an address. The & operator fetches the address of a variable, and the * operator accesses the value at that address. Internally, Go uses these addresses to read or write memory directly. The runtime tracks pointers to manage memory safely and perform garbage collection.
Why designed this way?
Go was designed to be safe and simple. Allowing pointers without arithmetic avoids many bugs common in lower-level languages. The design balances performance and safety by enabling direct memory access while preventing unsafe operations. This helps developers write efficient code without risking memory corruption.
 +-----------------+       +-----------------+
 |   Variable x    |       |   Pointer p     |
 |  Value: 42      |       |  Value: 0x123   |
 +-----------------+       +-----------------+
          ^                         |
          |                         v
      Memory address 0x123  ---->  Points to x's value

Operations:
 &x  -> get address 0x123
 *p  -> get value 42 at address 0x123
Myth Busters - 4 Common Misconceptions
Quick: Does declaring a pointer variable allocate memory for the value it points to? Commit yes or no.
Common Belief:Declaring a pointer variable creates space for the actual value it will point to.
Tap to reveal reality
Reality:Declaring a pointer only allocates space for the address, not the value itself. The value must exist separately.
Why it matters:Assuming the value exists can cause runtime errors when dereferencing uninitialized pointers.
Quick: Can you perform arithmetic like adding 1 to a pointer in Go? Commit yes or no.
Common Belief:You can do pointer arithmetic in Go just like in C or C++.
Tap to reveal reality
Reality:Go does not allow pointer arithmetic to keep memory access safe and predictable.
Why it matters:Trying pointer arithmetic leads to compile errors and misunderstanding Go's safety model.
Quick: Does passing a pointer to a function copy the data it points to? Commit yes or no.
Common Belief:Passing a pointer to a function copies the data the pointer points to.
Tap to reveal reality
Reality:Passing a pointer copies only the address, so the function accesses the original data.
Why it matters:Misunderstanding this causes confusion about why changes inside functions affect original variables.
Quick: Is a nil pointer safe to dereference? Commit yes or no.
Common Belief:A nil pointer can be dereferenced safely and just returns zero values.
Tap to reveal reality
Reality:Dereferencing a nil pointer causes a runtime panic (crash).
Why it matters:Ignoring nil checks leads to program crashes and unstable behavior.
Expert Zone
1
Pointers in Go are strongly typed, meaning a *int pointer cannot point to a string variable, preventing type errors.
2
The Go runtime uses pointers to track live objects for garbage collection, so pointers influence memory management.
3
Using pointers to structs allows efficient updates without copying large data, but requires careful handling to avoid nil dereferences.
When NOT to use
Avoid pointers when you only need to read data without modification, as copying small values is simpler and safer. For complex shared state, consider channels or sync primitives instead of raw pointers to avoid race conditions.
Production Patterns
In real-world Go code, pointers are used to modify structs in functions, implement linked data structures, and optimize performance by avoiding copies. They are also common in interfaces and methods to allow mutation of receiver objects.
Connections
References in C++
Pointers in Go and references in C++ both allow indirect access to variables but differ in syntax and safety.
Understanding Go pointers helps grasp how C++ references work and why Go chooses explicit pointer syntax for clarity.
Memory addresses in computer architecture
Pointers directly represent memory addresses, linking programming concepts to hardware memory layout.
Knowing how pointers map to physical memory deepens understanding of how programs interact with hardware.
Human navigation with maps
Pointers are like map coordinates that guide you to a location without carrying the location's contents.
This connection shows how indirect references simplify complex navigation, similar to how pointers simplify data access.
Common Pitfalls
#1Dereferencing a nil pointer causing a crash.
Wrong approach:var p *int fmt.Println(*p) // dereferencing nil pointer
Correct approach:var p *int if p != nil { fmt.Println(*p) } else { fmt.Println("Pointer is nil") }
Root cause:Not checking if a pointer is nil before dereferencing leads to runtime panics.
#2Confusing pointer declaration with value declaration.
Wrong approach:var p int = &x // wrong: assigning address to int variable
Correct approach:var p *int = &x // correct: p is pointer to int
Root cause:Misunderstanding that pointers require * before the type to hold addresses.
#3Expecting pointer arithmetic to work in Go.
Wrong approach:p = p + 1 // invalid: Go does not support pointer arithmetic
Correct approach:// Instead, use slices or arrays for indexed access
Root cause:Assuming Go pointers behave like C pointers causes compile errors and confusion.
Key Takeaways
Pointers store memory addresses, not the actual data values.
The & operator gets a variable's address; the * operator accesses the value at that address.
Dereferencing nil pointers causes runtime errors, so always check for nil before use.
Go disallows pointer arithmetic to keep programs safe and predictable.
Passing pointers to functions allows modifying original variables efficiently.

Practice

(1/5)
1. What does a pointer in Go store?
easy
A. The actual value of a variable
B. The memory address of a variable
C. The type of a variable
D. The size of a variable

Solution

  1. Step 1: Understand what a pointer represents

    A pointer does not hold the value itself but the location where the value is stored in memory.
  2. Step 2: Recall pointer definition in Go

    In Go, a pointer stores the address of a variable, not the variable's value directly.
  3. Final Answer:

    The memory address of a variable -> Option B
  4. Quick Check:

    Pointer = memory address [OK]
Hint: Pointers always hold addresses, not values [OK]
Common Mistakes:
  • Thinking pointers store the actual value
  • Confusing pointer with variable type
  • Assuming pointer stores variable size
2. Which of the following is the correct way to declare a pointer to an int variable named num in Go?
easy
A. var p int = &num
B. var p *int = num
C. var p *int = &num
D. var p int = *num

Solution

  1. Step 1: Understand pointer declaration syntax

    In Go, to declare a pointer to an int, use *int as the type.
  2. Step 2: Assign the address of num to the pointer

    The address operator & gets the memory address of num, which can be assigned to the pointer.
  3. Final Answer:

    var p *int = &num -> Option C
  4. Quick Check:

    Pointer declaration uses *type and &variable [OK]
Hint: Pointer type uses * before type, assign with &variable [OK]
Common Mistakes:
  • Forgetting the * in pointer type
  • Assigning variable value instead of address
  • Using *num instead of &num for assignment
3. What will be the output of this Go program?
package main
import "fmt"
func main() {
  x := 10
  p := &x
  *p = 20
  fmt.Println(x)
}
medium
A. 20
B. 10
C. Memory address of x
D. Compilation error

Solution

  1. Step 1: Understand pointer assignment and dereferencing

    Variable p stores the address of x. Using *p = 20 changes the value at that address.
  2. Step 2: Check the effect on x

    Since p points to x, changing *p changes x to 20.
  3. Final Answer:

    20 -> Option A
  4. Quick Check:

    Dereferencing pointer changes original variable [OK]
Hint: Changing *p changes the original variable [OK]
Common Mistakes:
  • Thinking *p creates a new variable
  • Expecting output to be address instead of value
  • Confusing pointer declaration with dereferencing
4. Identify the error in this Go code snippet:
var a int = 5
var p *int = a
fmt.Println(*p)
medium
A. Cannot assign int to *int without & operator
B. Cannot print pointer value with * operator
C. Variable a must be a pointer
D. Missing import fmt

Solution

  1. Step 1: Check pointer assignment rules

    Pointer variables must be assigned the address of a variable, not the variable's value.
  2. Step 2: Identify missing & operator

    Assigning a directly to p is invalid; it should be p = &a.
  3. Final Answer:

    Cannot assign int to *int without & operator -> Option A
  4. Quick Check:

    Pointer assignment needs &variable [OK]
Hint: Use & to assign address to pointer variables [OK]
Common Mistakes:
  • Assigning value instead of address to pointer
  • Forgetting to import fmt for Println
  • Thinking *p prints address instead of value
5. Given the code below, what will be the output?
package main
import "fmt"
func updateValue(p *int) {
  *p = *p + 5
}
func main() {
  val := 10
  updateValue(&val)
  fmt.Println(val)
}
hard
A. 10
B. Compilation error
C. Memory address of val
D. 15

Solution

  1. Step 1: Understand function parameter as pointer

    The function updateValue takes a pointer to an int and modifies the value at that address.
  2. Step 2: Trace the function call and modification

    Passing &val sends the address of val. Inside the function, *p = *p + 5 increases val by 5.
  3. Step 3: Check final print output

    After the function call, val is updated to 15, so fmt.Println(val) prints 15.
  4. Final Answer:

    15 -> Option D
  5. Quick Check:

    Pointer parameter modifies original variable [OK]
Hint: Passing &variable lets function change original value [OK]
Common Mistakes:
  • Passing value instead of address to function
  • Expecting original variable unchanged
  • Confusing pointer dereference syntax
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard