Go Pointers

A pointer stores the memory address of another variable rather than a value directly. Pointers allow functions to modify the original data they point to and help avoid expensive copies of large data structures.

Understanding Memory Addresses

x := 42

Memory:
┌──────────────────────────┐
│  Address: 0xc0000b4010   │
│  Variable: x             │
│  Value: 42               │
└──────────────────────────┘

A pointer stores the address: 0xc0000b4010

Declaring and Using a Pointer

Use & to get the address of a variable. Use * to read or change the value at that address.

package main

import "fmt"

func main() {
    x := 42

    p := &x           // p is a pointer to x

    fmt.Println(x)    // 42     — the value
    fmt.Println(&x)   // 0x...  — the address of x
    fmt.Println(p)    // 0x...  — same address stored in p
    fmt.Println(*p)   // 42     — the value at the address (dereference)

    *p = 100          // change x through the pointer
    fmt.Println(x)    // 100
}

Pointer Operators

OperatorNameWhat It Does
&Address-ofGets the memory address of a variable
*DereferenceReads or writes the value at an address

Pointers in Functions

Without a pointer, a function receives a copy of the value. Changes inside the function do not affect the original.

package main

import "fmt"

// Without pointer – changes do NOT affect original
func doubleByValue(n int) {
    n = n * 2
}

// With pointer – changes DO affect original
func doubleByPointer(n *int) {
    *n = *n * 2
}

func main() {
    a := 10
    doubleByValue(a)
    fmt.Println(a) // 10 — unchanged

    b := 10
    doubleByPointer(&b)
    fmt.Println(b) // 20 — changed
}

Pointer to a Struct

Passing a pointer to a struct lets a function modify the struct's fields directly. Go also allows accessing fields through a pointer without explicit dereferencing.

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func birthday(p *Person) {
    p.Age++  // Go automatically dereferences — same as (*p).Age++
}

func main() {
    alice := Person{Name: "Alice", Age: 29}
    birthday(&alice)
    fmt.Println(alice.Age) // 30
}

new() Function

The new function allocates memory for a type, sets it to zero, and returns a pointer to it.

package main

import "fmt"

func main() {
    p := new(int)    // p is *int, pointing to value 0
    *p = 55
    fmt.Println(*p)  // 55
}

Nil Pointer

A pointer with no address assigned has the value nil. Dereferencing a nil pointer causes a panic.

package main

import "fmt"

func main() {
    var p *int
    fmt.Println(p)    // 

    if p != nil {
        fmt.Println(*p)
    } else {
        fmt.Println("pointer is nil — cannot dereference")
    }
}

When to Use Pointers

SituationUse Pointer?
Function needs to modify the caller's variableYes
Large struct — avoid copyingYes
Small value, read-only useNo — pass by value
Representing optional/absent valueYes — nil pointer means absent

Key Points

  • A pointer stores the memory address of another variable
  • &x gets the address of x; *p reads or writes the value at address p
  • Functions with pointer parameters can modify the original variable
  • Go automatically dereferences struct pointers when accessing fields
  • Always check for nil before dereferencing to avoid panics

Leave a Comment