Search code examples
gopointersmemory-managementgarbage-collectionruntime-error

Why does Go not throw an error when dereferencing a dangling pointer immediately after a variable goes out of scope?


I’m learning about Go’s memory management and garbage collection, and I’ve encountered some unexpected behavior when trying to dereference a pointer after the variable it points to goes out of scope.

In Go, I understand that garbage collection (GC) is automatic and that pointers can sometimes reference memory that is no longer valid. I expected that dereferencing a pointer to an out-of-scope variable would throw an error, but it seems like Go doesn't throw an error when doing so

Here’s a minimal example that demonstrates the issue:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    var p *int
    {
        x := 42
        p = &x  // p points to x
        fmt.Println(*p) // Prints 42
    }

    // Force garbage collection (for testing)
    runtime.GC()

    // Dereferencing p here should cause an error (since x is out of scope)
    fmt.Println(*p) // This does NOT throw any error
}

What I expected:

  • I expected that after the inner block where x goes out of scope, the pointer p would be a "dangling pointer" and would immediately cause a runtime error when dereferenced.
  • The error I expected is something like: runtime: invalid memory address or nil pointer dereference.

What actually happens:

  • The program does not panic or throw an error when dereferencing *p even after forcing garbage collection. The value printed is still the address of x even though x is out of scope.

Solution

  • The GC does not care about the scope. It checks if there are active pointers to a memory object. In your case, there is at least one.

    The variable x may be out of scope, but p is not, and it is pointing to x, and there is a goroutine using p, so x will not be garbage collected. It will be ready for collection after the function returns, because p will be out of scope as well.