Pointers and Memory

Back

Loading concept...

🏠 Pointers and Memory in Go: Your Home Address Adventure!

Imagine you have a house. Your house has stuff inside (like toys, books, games). But your house also has an address — the street number that tells the mailman where to find you!

In Go, pointers work just like home addresses. Instead of carrying your whole house around, you just share the address. Simple, right?


🎯 What We’ll Explore

  1. Pointer Basics — What’s an address in computer land?
  2. Pointer Operations — Getting and using addresses
  3. nil Pointer — When there’s no address yet
  4. new Function — Building a new house instantly
  5. Addressability Rules — What can have an address?
  6. Value vs Reference — Copying the house vs sharing the address

1️⃣ Pointer Basics — Understanding Addresses

The Big Idea

A pointer is just an address. It tells Go: “Hey, the thing you want lives over THERE!”

Real Life Example

Your friend asks: "Where's your toy box?"

Option 1: You carry the WHOLE toy box to them (heavy!)
Option 2: You tell them "It's in my room, shelf 3" (easy!)

Option 2 is a pointer — you shared the location, not the thing itself!

In Go Code

age := 10           // A variable (the toy box)
ptr := &age         // A pointer (the address)

fmt.Println(age)    // Prints: 10
fmt.Println(ptr)    // Prints: 0xc0000... (an address!)

Key Symbol: *

The * symbol means “pointer to something.”

var p *int    // p is a pointer to an integer
              // (p will hold an ADDRESS where an int lives)

Think of *int as: “This is a sticky note that has a house address written on it, and at that house lives a number!”


2️⃣ Pointer Operations — The Two Magic Symbols

Meet & and *

Symbol What It Does Memory Trick
& “Give me the ADDRESS of this thing” Ampersand = Address
* “Go TO this address and get the thing” Star = “Go far” to find it

Getting an Address with &

score := 100
address := &score   // & gives us the address

fmt.Println(address)  // 0xc000018030 (some memory location)

Reading What’s at an Address with *

score := 100
address := &score

value := *address   // * means "look inside this address"
fmt.Println(value)  // Prints: 100

Changing What’s at an Address

Here’s the magic — you can change the original value through its pointer!

cookies := 5
ptr := &cookies

*ptr = 10           // Go to that address, change the value!

fmt.Println(cookies) // Prints: 10 (it changed!)

Story Time: The Cookie Jar

You have a cookie jar with 5 cookies.
You give your friend a map to the cookie jar.
Your friend follows the map and adds 5 more cookies.
Now when YOU look at the jar — surprise! 10 cookies!

Both you and your friend were looking at the same jar, not copies!


3️⃣ nil Pointer — The Empty Address

What is nil?

nil means “no address” or “pointing to nothing.”

It’s like having a blank sticky note — you haven’t written any address on it yet!

var ptr *int        // Declared but not assigned
fmt.Println(ptr)    // Prints: <nil>

⚠️ Danger Zone!

If you try to use a nil pointer, Go will crash!

var ptr *int        // ptr is nil
*ptr = 42           // CRASH! There's no address to go to!

Safe Pointer Usage

Always check if a pointer is nil before using it:

var ptr *int

if ptr != nil {
    fmt.Println(*ptr)
} else {
    fmt.Println("Pointer is empty!")
}

Think of it Like This

Trying to visit a nil pointer is like:
"Go to the house at address ____"
"But... there's no address written here!"

4️⃣ The new Function — Instant House Builder

What Does new() Do?

The new() function:

  1. Creates space in memory for a value
  2. Sets that space to zero (empty)
  3. Gives you the address of that space
ptr := new(int)     // Creates an int, gives you its address
fmt.Println(*ptr)   // Prints: 0 (the default "zero" value)

*ptr = 42           // Now put 42 at that address
fmt.Println(*ptr)   // Prints: 42

new() vs Regular Variables

// Method 1: Regular way
x := 0
ptr1 := &x

// Method 2: Using new()
ptr2 := new(int)    // Same result, but x doesn't exist as a name

When to Use new()

Use new() when you need a pointer right away but don’t need a named variable:

// Creating a pointer to a struct
person := new(Person)
person.Name = "Alex"
person.Age = 10

5️⃣ Addressability Rules — What CAN Have an Address?

Not everything in Go can have its address taken! Let’s learn the rules.

✅ CAN Take Address Of:

Thing Example Why
Variables &myVar They have a home in memory
Struct fields &person.Name Part of a variable
Array elements &arr[0] They’re stored somewhere
Slice elements &slice[2] Points to backing array

❌ CANNOT Take Address Of:

Thing Example Why Not
Constants &100 They’re not stored anywhere specific
Literals &"hello" Same reason
Function results &getName() Result is temporary
Map values &myMap["key"] Maps can move things around!

Code Examples

// ✅ This works
name := "Go"
ptr := &name

// ❌ This fails
// ptr := &"Hello"  // Can't take address of a literal!

// ❌ This fails too
myMap := map[string]int{"score": 100}
// ptr := &myMap["score"]  // Can't take address of map value!

The Rule in Simple Words

If something has a permanent home in memory, you can get its address. If it’s temporary or might move, you can’t!


6️⃣ Value vs Reference Semantics — The Big Choice

This is the most important concept! Let’s master it.

Value Semantics: Making Copies

When you pass a variable normally, Go makes a copy:

func double(n int) {
    n = n * 2     // Only changes the copy!
}

func main() {
    num := 5
    double(num)
    fmt.Println(num)  // Still 5! The original didn't change.
}

Reference Semantics: Sharing the Address

When you pass a pointer, you share the original:

func double(n *int) {
    *n = *n * 2   // Changes the original!
}

func main() {
    num := 5
    double(&num)
    fmt.Println(num)  // Now 10! The original changed.
}

The Pizza Story 🍕

VALUE SEMANTICS:
You have a pizza recipe. You give your friend a COPY.
They add extra cheese to THEIR copy.
Your recipe stays the same!

REFERENCE SEMANTICS:
You share the ACTUAL recipe card with your friend.
They add extra cheese to it.
Now YOUR recipe also has extra cheese!

When to Use Each?

Use Value (Copy) When… Use Reference (Pointer) When…
Data is small (int, bool) Data is large (big structs)
You want safety from changes You need to modify the original
You want predictable behavior You want to save memory

Visual Flow

graph TD A["Function Call"] --> B{What to Pass?} B -->|Small data, don't modify| C["Pass by Value"] B -->|Large data or need to modify| D["Pass by Pointer"] C --> E["Safe copy created"] D --> F["Original data shared"]

🎯 Quick Summary

Concept What It Is Symbol
Pointer An address in memory *int
Get address Find where something lives &
Dereference Look at what’s at an address *
nil Empty/no address nil
new() Create memory, get address new(type)
Value semantics Work with copies Normal params
Reference semantics Share the original Pointer params

🌟 Remember This!

  1. & = “What’s your address?”
  2. * = “Let me visit that address”
  3. nil = “No address written yet”
  4. new() = “Build me a house and give me the address”
  5. Value = Copy the whole thing
  6. Reference = Share the location

You’ve now mastered the art of pointers in Go! They’re just addresses — nothing scary about knowing where things live! 🏠✨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.