0

0

如何存储指针指向的地址?

DDD

DDD

发布时间:2025-08-01 18:24:16

|

582人浏览过

|

来源于php中文网

原创

如何存储指针指向的地址?

本文旨在讲解如何在 Go 语言中存储 new() 函数返回的指针所指向的内存地址。虽然可以使用 unsafe 包中的 Pointer 类型,但存在潜在的安全风险。本文将探讨更安全且更实用的方法,并简要介绍 reflect 和 unsafe 包的相关用法,帮助开发者更好地理解和使用指针地址。

在 Go 语言中,如果你需要存储 new() 函数分配的内存地址,并将其用作 map 的键,直接使用指针类型可能会遇到问题,因为 Go 是一种类型安全的语言。以下是一些建议和方法,帮助你安全有效地存储和使用指针地址。

使用 unsafe.Pointer (不推荐)

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)
}

注意事项:

  • 使用 unsafe.Pointer 需要谨慎,因为它可能导致程序崩溃或产生未定义的行为。
  • 在垃圾回收过程中,如果指针不再被引用,内存可能会被释放,导致 unsafe.Pointer 指向无效的内存地址。
  • 不建议从 uintptr 转换回原始指针类型,除非你非常确定内存仍然有效。

使用类型和地址的元组

更安全和推荐的方法是使用类型和地址的元组作为 map 的键。这可以确保类型安全,并避免 unsafe 包的潜在风险。虽然这种方法增加了复杂性,但它提供了更好的控制和安全性。

ADHD Reading
ADHD Reading

面向ADHD群体的浏览器阅读增强扩展

下载
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)
    }
}

代码解释:

  1. AddressKey 结构体: 定义了一个结构体,用于存储类型信息 (reflect.Type) 和地址 (uintptr)。
  2. reflect.TypeOf(ptr).Elem(): 获取指针 ptr 指向的类型,例如 T。
  3. reflect.ValueOf(ptr).Pointer(): 获取指针 ptr 的地址,返回 uintptr 类型。
  4. memmap[key] = t: 将 AddressKey 结构体作为键,将时间戳 t 作为值,存储到 map 中。

优点:

  • 类型安全:使用 reflect 包获取类型信息,避免了直接使用 unsafe.Pointer 带来的类型安全问题。
  • 明确性:明确地存储了类型信息和地址信息,方便后续使用。

缺点:

  • 复杂性:相比直接使用 unsafe.Pointer,代码更加复杂。
  • 性能:使用 reflect 包可能会带来一定的性能损耗。

总结

在 Go 语言中存储指针地址需要谨慎。虽然可以使用 unsafe.Pointer,但存在安全风险。更安全的方法是使用类型和地址的元组,这需要使用 reflect 包获取类型信息和地址信息。选择哪种方法取决于你的具体需求和对安全性的考虑。建议优先选择类型安全的方案,避免使用 unsafe 包,除非你有充分的理由并且了解潜在的风险。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

530

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

204

2025.07.04

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

77

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

41

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

47

2025.11.27

JavaScript中的typeof用法
JavaScript中的typeof用法

在JavaScript中,typeof是一个用来确定给定变量的数据类型的操作符。可以用来确定一个变量是字符串、数字、布尔值、函数、对象或undefined的数据类型。更多关于typeof用法相关文章,详情请看本专题下面的文章,php中文网欢迎大家前来学习。

771

2023.11.23

Go Web框架Gin接口开发与中间件设计实践
Go Web框架Gin接口开发与中间件设计实践

本专题围绕 Go 在 Web 后端开发中的主流框架 Gin 展开,系统讲解高性能接口开发与中间件机制设计。内容涵盖路由分组、请求绑定、参数校验、统一响应封装、日志与鉴权中间件实现,以及接口限流与异常处理策略。通过实战项目案例,帮助开发者构建结构清晰、性能优良的 Go Web 服务体系,提升接口开发效率与系统可维护性。

7

2026.03.19

bootstrap安装教程
bootstrap安装教程

本专题整合了bootstrap安装相关教程,阅读专题下面的文章了解更多详细操作教程。

27

2026.03.18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 1.0万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号