Go指针运算的实现

ByWhat'sUs

Go指针运算的实现

unsafe.Pointer 是一个万能指针,可以在任何指针类型之间做转化,这就绕过了 Go 的类型安全机制,所以是不安全的操作。

uintptr 是 Go 内置的可用于存储指针的整型,而整型是可以进行数学运算的!因此,将 unsafe.Pointer 转化为 uintptr 类型后,就可以让本不具备运算能力的指针具备了指针运算能力:

arr := [3]int{1, 2, 3}
ap := &arr
sp := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(ap)) + unsafe.Sizeof(arr[0])))
*sp += 3
fmt.Println(arr)

这里,我们将数组 arr 的内存地址赋值给指针 ap,然后通过 unsafe.Pointer 这个桥梁转化为 uintptr 类型,再加上数组元素偏移量(通过 unsafe.Sizeof 函数获取),就可以得到该数组第二个元素的内存地址,最后通过 unsafe.Pointer 将其转化为 int 类型指针赋值给 sp 指针,并进行修改,最终打印的结果是:

[1 5 3]

这样一来,就可以绕过 Go 指针的安全限制,实现对指针的动态偏移和计算了,这会导致即使发生数组越界了,也不会报错,而是返回下一个内存地址存储的值,这就破坏了内存安全限制,所以这也是不安全的操作,我们在实际编码时要尽量避免使用,必须使用的话也要非常谨慎。

About the author

What'sUs administrator

Leave a Reply

PHP Code Snippets Powered By : XYZScripts.com