4个回答

golang面试题:能说说uintptr和unsafe.Pointer的区别吗?

秋生

uintptrunsafe.Pointer 都属于 Go 语言中的指针类型,内部实现方式略有不同。

首先我们知道,任何指针都有一个地址(也就是指向的内存单元的位置)以及一些其他的元数据,比如类型信息、大小等等,这些元数据存储在指针本身所指向的内存单元中。在 Go 语言中使用的指针类型中,uintptr 和 unsafe.Pointer 之间并没有太大的区别,基本可以互换使用,但是具体使用时需要提及到一些细节。

  • uintptr的定义:uintptr 是 Go 语言中的一种整数类型,可以用来存储一个指针类型的值。此类型的值不会被回收,所以它引用的对象将不会成为垃圾对象。uintptr 类型的值可以在对指针进行转换时使用,因为在 Go 中,指针可以自由地转换为任意类型的指针。
  • unsafe.Pointer的定义:unsafe.Pointer 是 Go 语言标准库中的一个类型。它可以用来存储任意类型的指针,这包括所有的指针类型,甚至是函数指针。该类型应该谨慎使用,因为它将绕过所有的类型安全机制,容易导致程序崩溃和内存泄漏等问题。

从上面的定义可以看出,uintptr 是一种无类型指针,实际上它只是一个字段,保存了指向的内存单元的地址,没有类型标识。而unsafe.Pointer 是一种从指针类型向另一种指针类型不安全转换的工具,可以保存任何类型的地址,并允许对其进行指针算术运算(如加减操作)甚至直接使用(如打印指针地址)。它常用于将指针转换为指向未定义类型的指针,并允许进行类型转换、算术运算以及向内存的任意位置写入数据等操作。

在使用时,如果需要将任意类型的指针转换为 uintptr 类型,则需要使用 Go 语言中的 unsafe 包中的 uintptr 函数。而如果需要将 uintptr 类型的指针转换为任意类型的指针,则需要使用 unsafe.Pointer 函数。

需要注意的是,使用 uintptr 类型的指针时要格外小心,因为 Go 语言的内存分配方式和垃圾回收机制可能会使地址变更。如果使用了一个被移动过的内存地址,那么很可能会引发不可预知的错误。此外,对于内存安全这一特性, uintptr 类型指针没有任何保障,只有在确保代码逻辑正确且不会出问题时再去考虑使用。

发布于 2023-03-05 13:29・IP 属地澳大利亚
马甲
自由评论 (0)
分享
Copyright © 2022 GreatFire.org