Skip to main content

Go Ep 7: Pointers & Memory Allocation

Rachmat Hidayat
Author
Rachmat Hidayat
Learn & sharing insights on TypeScript, Go, Kubernetes, DevOps, DevSecOps, SRE, Platform Engineering, AI/ML Engineering, and MLOps.
go - This article is part of a series.
Part 7: This Article
Go is a pass-by-value language. When you pass an argument to a function, Go creates a copy. Pointers allow you to share memory directly across function boundaries without copying large data structures.

TL;DR (Quick Summary)
#

  • & (Address-Of): Returns the memory address pointer of a variable.
  • * (Dereference): Accesses or mutates the value stored at a pointer’s memory address.
  • Stack Allocation: Fast, automatic cleanup when the function returns.
  • Heap Allocation: Slower, managed by the Garbage Collector. Happens when variables escape local function scope.
  • Escape Analysis: go build -gcflags="-m" inspects whether variables escape to the heap.

1. Pointer Mechanics Visualized
#


graph LR
    SubGraphMemory["RAM Memory"] --> Address["Address: 0xc000014080"]
    Address --> Value["Value: 42 (int)"]

    SubGraphPointer["Pointer Variable"] --> PtrVar["ptr *int = 0xc000014080"]
    PtrVar -->|Dereference *ptr| Value
package main

import "fmt"

func double(val *int) {
	*val = *val * 2 // Dereference and mutate memory value directly
}

func main() {
	x := 21
	fmt.Println("Before:", x) // 21

	double(&x) // Pass memory address of x
	fmt.Println("After:", x)  // 42
}

2. Escape Analysis (go build -gcflags="-m")
#

The Go compiler automatically determines whether a variable can be safely allocated on the fast Stack or must escape to the Heap.

package main

type Config struct {
	Endpoint string
}

// Escapes to heap because pointer is returned outside function scope
func NewConfig() *Config {
	c := Config{Endpoint: "https://api.work.com"}
	return &c // Escapes to Heap!
}

func main() {
	cfg := NewConfig()
	_ = cfg
}

Run compiler escape analysis:

go build -gcflags="-m" main.go

Expected Terminal Output:

./main.go:10:2: &c escapes to heap
./main.go:10:2: moved to heap: c

3. Comparison: make vs new
#

OperatorAllocatesInitializesReturn TypeTarget Types
new(T)Zeroed MemoryNo*T (Pointer)All Types (new(User), new(int)).
make(T, args)Internal Data HeadersYesT (Value)Slices, Maps, Channels ONLY.

4. Troubleshooting & Common Errors
#

Error 1: Nil Pointer Dereference Panic
#

The Cause: Dereferencing a pointer that points to address 0x0 (nil).

var u *User
fmt.Println(u.Name) // 💥 panic: runtime error: invalid memory address or nil pointer dereference

The Fix: Initialize the struct or perform a nil check before accessing fields.


Summary & Next Steps
#

In this episode:

  • We used & address-of and * dereference operators.
  • We analyzed pass-by-value vs pass-by-reference semantics.
  • We ran compiler Escape Analysis (-gcflags="-m").

In Episode 8: Methods & Struct Composition, we will attach methods to structs and replace inheritance with Composition!

go - This article is part of a series.
Part 7: This Article