Golang uintptr type
last modified May 8, 2025
This tutorial explains how to use the uintptr
built-in type in Go.
We'll cover low-level pointer operations with practical examples of memory
address manipulation.
The uintptr is an integer type that is large enough to hold the bit pattern of any pointer. It's primarily used for unsafe pointer arithmetic when interacting with system calls or C libraries.
In Go, uintptr
is often used with the unsafe
package
for low-level programming. It represents memory addresses as unsigned integers,
allowing arithmetic operations on pointers.
Basic uintptr usage
This example demonstrates converting a pointer to uintptr and back. It shows
the basic relationship between pointers and uintptr values.
Note: These operations require the unsafe package.
package main import ( "fmt" "unsafe" ) func main() { var x int = 42 ptr := &x // Convert pointer to uintptr addr := uintptr(unsafe.Pointer(ptr)) fmt.Printf("Pointer: %p\n", ptr) fmt.Printf("Address as uintptr: 0x%x\n", addr) // Convert back to pointer newPtr := (*int)(unsafe.Pointer(addr)) fmt.Println("Value through new pointer:", *newPtr) }
The code converts a pointer to uintptr and back safely. The uintptr holds the memory address as an integer value, which can be printed or manipulated.
Pointer arithmetic with uintptr
This example shows how to perform pointer arithmetic using uintptr to access struct fields. It demonstrates calculating field offsets.
package main import ( "fmt" "unsafe" ) type Person struct { name string age int } func main() { p := Person{"Alice", 30} base := unsafe.Pointer(&p) // Calculate name field address namePtr := (*string)(unsafe.Pointer(base)) fmt.Println("Name:", *namePtr) // Calculate age field address agePtr := (*int)(unsafe.Pointer(uintptr(base) + unsafe.Offsetof(p.age))) fmt.Println("Age:", *agePtr) }
The code uses uintptr arithmetic to access struct fields directly. The
unsafe.Offsetof
function helps calculate field offsets safely.
Converting between uintptr and unsafe.Pointer
This example demonstrates proper conversion patterns between uintptr and unsafe.Pointer. It shows temporary uintptr usage in a single expression.
package main import ( "fmt" "unsafe" ) func main() { data := []byte{'G', 'o', 'l', 'a', 'n', 'g'} // Safe conversion pattern firstChar := *(*byte)(unsafe.Pointer( uintptr(unsafe.Pointer(&data[0])))) // Unsafe pattern (don't do this) // addr := uintptr(unsafe.Pointer(&data[0])) // ... potential GC here ... // firstChar := *(*byte)(unsafe.Pointer(addr)) fmt.Printf("First character: %c\n", firstChar) }
The safe pattern keeps the conversion in one expression. Storing uintptr in variables can lead to issues if garbage collection occurs.
System call with uintptr
This example shows uintptr usage in system calls, where memory addresses must be passed as integers. It demonstrates Windows API call pattern.
package main import ( "fmt" "syscall" "unsafe" ) func main() { user32 := syscall.NewLazyDLL("user32.dll") msgBox := user32.NewProc("MessageBoxW") text, _ := syscall.UTF16PtrFromString("Hello from Go!") caption, _ := syscall.UTF16PtrFromString("uintptr Example") // Convert pointers to uintptr for syscall ret, _, _ := msgBox.Call( 0, uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), 0) fmt.Printf("MessageBox returned: %d\n", ret) }
The syscall requires uintptr arguments. The code converts string pointers to uintptr values for the Windows API call. This is a common pattern in FFI.
Memory inspection with uintptr
This example demonstrates using uintptr to inspect memory layout. It shows how to examine the internal structure of a slice.
package main import ( "fmt" "unsafe" ) func main() { s := []int{10, 20, 30} // Get slice header header := (*[3]uintptr)(unsafe.Pointer(&s)) // Extract slice components ptr := header[0] len := header[1] cap := header[2] fmt.Printf("Pointer: 0x%x\n", ptr) fmt.Printf("Length: %d\n", len) fmt.Printf("Capacity: %d\n", cap) // Access first element first := *(*int)(unsafe.Pointer(ptr)) fmt.Println("First element:", first) }
The code uses uintptr to examine the slice header structure. This reveals the underlying array pointer, length, and capacity values stored in the slice.
Source
This tutorial covered the uintptr
type in Go with practical
examples of low-level memory operations and system interactions.
Author
List all Golang tutorials.