
本文旨在讲解如何在 Go 语言中存储 new() 函数返回的指针所指向的内存地址。虽然可以使用 unsafe 包中的 Pointer 类型,但存在潜在的安全风险。本文将探讨更安全且更实用的方法,并简要介绍 reflect 和 unsafe 包的相关用法,帮助开发者更好地理解和使用指针地址。
在 Go 语言中,如果你需要存储 new() 函数分配的内存地址,并将其用作 map 的键,直接使用指针类型可能会遇到问题,因为 Go 是一种类型安全的语言。以下是一些建议和方法,帮助你安全有效地存储和使用指针地址。
unsafe 包提供了一种将任何类型的指针转换为 unsafe.Pointer 的方法。unsafe.Pointer 可以转换为 uintptr,后者可以作为 map 的键。但是,使用 unsafe 包具有潜在的风险,因为它绕过了 Go 的类型安全检查。
package main
import (
"fmt"
"time"
"unsafe"
)
type T struct {
a, b int
}
func main() {
var t int64 = time.Now().UnixNano()
memmap := make(map[uintptr]int64)
fmt.Printf("%d\n", t)
var ptr *T = new(T)
ptr.a = 1
ptr.b = 2
fmt.Printf("%d %d %p %T\n", ptr.a, ptr.b, ptr, ptr)
// 将指针转换为 unsafe.Pointer,再转换为 uintptr
addr := uintptr(unsafe.Pointer(ptr))
memmap[addr] = t
fmt.Printf("Address stored in map: %x\n", addr)
// 从map中取出数据,需要将uintptr转换回指针才能访问原始数据,非常危险!
// 强烈不建议这样做
// restoredPtr := (*T)(unsafe.Pointer(addr))
// fmt.Printf("Restored value: %d %d\n", restoredPtr.a, restoredPtr.b)
}注意事项:
更安全和推荐的方法是使用类型和地址的元组作为 map 的键。这可以确保类型安全,并避免 unsafe 包的潜在风险。虽然这种方法增加了复杂性,但它提供了更好的控制和安全性。
package main
import (
"fmt"
"reflect"
"time"
)
type T struct {
a, b int
}
type AddressKey struct {
Type reflect.Type
Addr uintptr
}
func main() {
var t int64 = time.Now().UnixNano()
memmap := make(map[AddressKey]int64)
fmt.Printf("%d\n", t)
var ptr *T = new(T)
ptr.a = 1
ptr.b = 2
fmt.Printf("%d %d %p %T\n", ptr.a, ptr.b, ptr, ptr)
// 使用 reflect 获取类型信息和地址
key := AddressKey{
Type: reflect.TypeOf(ptr).Elem(), // 获取指针指向的类型
Addr: reflect.ValueOf(ptr).Pointer(), // 获取指针地址
}
memmap[key] = t
fmt.Printf("Address stored in map: %v\n", key)
// 从map中取出数据
value, ok := memmap[key]
if ok {
fmt.Printf("Value from map: %d\n", value)
}
}代码解释:
优点:
缺点:
在 Go 语言中存储指针地址需要谨慎。虽然可以使用 unsafe.Pointer,但存在安全风险。更安全的方法是使用类型和地址的元组,这需要使用 reflect 包获取类型信息和地址信息。选择哪种方法取决于你的具体需求和对安全性的考虑。建议优先选择类型安全的方案,避免使用 unsafe 包,除非你有充分的理由并且了解潜在的风险。
以上就是如何存储指针指向的地址?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号