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.