Pointers
Memory addresses and indirection
Introduction
In this lesson, you'll learn about pointers in Go. Coming from C, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In C, you're familiar with memory addresses and indirection.
Go has its own approach to memory addresses and indirection, which we'll explore step by step.
The Go Way
Let's see how Go handles this concept. Here's a typical example:
package main
import "fmt"
func increment(x *int) {
*x++
}
func main() {
a := 5
p := &a // p points to a
*p = 10 // dereference and assign
fmt.Println(a) // 10
increment(&a)
fmt.Println(a) // 11
// No pointer arithmetic in Go!
arr := []int{1, 2, 3}
fmt.Println(arr[1]) // use index, not ptr arithmetic
// nil pointer
var nullP *int = nil
// new() allocates on heap
q := new(int)
*q = 42
}Comparing to C
Here's how you might have written similar code in C:
#include <stdio.h>
void increment(int *x) {
(*x)++;
}
int main() {
int a = 5;
int *p = &a; /* p points to a */
*p = 10; /* dereference and assign */
printf("%d\n", a); /* 10 */
increment(&a);
printf("%d\n", a); /* 11 */
/* Pointer arithmetic */
int arr[3] = {1, 2, 3};
int *ptr = arr;
printf("%d\n", *(ptr + 1)); /* 2 */
/* NULL pointer */
int *null_p = NULL;
}You may be used to different syntax or behavior.
Go has & (address) and * (dereference) like C, but no pointer arithmetic
You may be used to different syntax or behavior.
Go's nil replaces C's NULL
You may be used to different syntax or behavior.
Go has new() for heap allocation; no malloc/free
You may be used to different syntax or behavior.
Go auto-dereferences struct pointer fields (p.Field not p->Field)
Step-by-Step Breakdown
1. Basic Pointers
Go uses the same & and * operators as C for address-of and dereference. The syntax feels identical.
int *p = &a; *p = 10;p := &a; *p = 102. No Pointer Arithmetic
Go deliberately omits pointer arithmetic to prevent memory corruption bugs. Use slice indices instead.
*(ptr + 2) = 99; // advance by 2 intsarr[2] = 99 // use index directly3. new() vs malloc()
Go's new(T) allocates a zero-valued T on the heap and returns *T. No need to call free — GC handles it.
int *p = malloc(sizeof(int)); *p = 42; free(p);p := new(int); *p = 42 // GC frees itCommon Mistakes
When coming from C, developers often make these mistakes:
- Go has & (address) and * (dereference) like C, but no pointer arithmetic
- Go's nil replaces C's NULL
- Go has new() for heap allocation; no malloc/free
Key Takeaways
- Go has & and * like C — syntax is the same
- No pointer arithmetic in Go — use slice indices
- nil replaces NULL
- new() replaces malloc(); GC replaces free()