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 包的潜在风险。虽然这种方法增加了复杂性,但它提供了更好的控制和安全性。

陌言AI
陌言AI

陌言AI是一个一站式AI创作平台,支持在线AI写作,AI对话,AI绘画等功能

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

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

344

2025.06.09

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

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

199

2025.07.04

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

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

77

2025.09.05

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

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

36

2025.11.16

golang map原理
golang map原理

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

67

2025.11.17

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

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

46

2025.11.27

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

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

763

2023.11.23

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

776

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

247

2026.02.13

热门下载

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

精品课程

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

共1课时 | 0.1万人学习

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

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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