乐趣区

关于go:go语言源码阅读指针unsafe包以及指针运算

一、意识指针与指针类型

一个指针变量能够指向任何一个值的内存地址,它所指向的值的内存地址在 32 和 64 位机器上别离占用 4 或 8 个字节,占用字节的大小与所指向的值的大小无关。当一个指针被定义后没有调配到任何变量时,它的默认值为 nil。

每个变量在运行时都领有一个地址,这个地址代表变量在内存中的地位。Go 语言中应用在变量名后面增加 & 操作符(前缀)来获取变量的内存地址(取地址操作),格局如下:

ptr := &v    // v 的类型为 T

其中 v 代表被取地址的变量,变量 v 的地址应用变量 ptr 进行接管,v 的类型为 T,ptr 的类型为 T,称做 T 的指针类型, 代表指针。

func TestPtr(t *testing.T) {
    s := "hello ptr"
    fmt.Printf("s 的地址为 %p , 地址的 10 进制示意为 %d 值为 %s \n", &s, &s, s)
    fmt.Printf("地址的 2 进制示意为 %b", &s)
}

输入:

 s 的地址为 0xc0000484e0 , 地址的 10 进制示意为 824634016992 值为 hello ptr
地址的 2 进制示意为 1100000000000000000001001000010011100000

问题 1:s 地址占用了几个字节?

如果咱们数一下大概有 40 位二进制,那么是 5 个字节?
正确答案是 8 个字节,咱们能够转为 unsafe.Pointer 而后应用 size 办法打印进去

func TestPtr(t *testing.T) {
    s := "hello ptr"
    fmt.Printf("s 的地址为 %p , 地址的 10 进制示意为 %d 值为 %s \n", &s, &s, s)
    fmt.Printf("s 地址的 2 进制示意为 %b \n", &s)

    var p unsafe.Pointer
    p = unsafe.Pointer(&s)
    fmt.Printf("p 地址的 2 进制示意为 %b \n", p)
    size := unsafe.Sizeof(p)
    fmt.Printf("p 地址的大小为几个字节 %d \n", size)
}

输入为:

 s 的地址为 0xc00008e4d0 , 地址的 10 进制示意为 824634303696 值为 hello ptr 
s 地址的 2 进制示意为 1100000000000000000010001110010011010000 
p 地址的 2 进制示意为 1100000000000000000010001110010011010000 
p 地址的大小为几个字节 8 

二、unsafe.Pointer 类型介绍

一、unsafe 包办法简略应用

type ArbitraryType int
type Pointer *ArbitraryType
func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr

1.Sizeof 指针内存大小

退出移动版