golang 指针的问题

2022-08-07 18:23:22 +08:00
 jeesk
func testMutex() {

	stu := &Stu{
		name: "song",
		age:  "12",
		s:    Stu1{name: "stu1"},
	}
	stu.st1 = &Stu{
		name: "i amstu.st1",
		age:  "",
		s:    Stu1{},
		st1:  nil,
	}
	// 获取第一个
	fmt.Println((*Stu)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)))).name)
	i := *(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("")))
	// 获取第二个
	fmt.Println(i)
	// 获取第三个
	ci := (*Stu1)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("") + unsafe.Sizeof("")))
	fmt.Println(ci.name)
	// 获取第四个
	ci1 := *(*Stu)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("") + unsafe.Sizeof("") + unsafe.Sizeof(stu.s)))
	fmt.Println(ci1)
}

type Stu struct {
	name string
	age  string
	s    Stu1
	st1  *Stu
}

type Stu1 struct {
	name string
}

代码如上。 我发现 这样搞, 获取不到 Stu 里面的 st1 指针对象。 尴尬住了

1679 次点击
所在节点    Go 编程语言
8 条回复
luguhu
2022-08-07 18:32:21 +08:00
unsafe.Sizeof(reflect.ValueOf(stu.s))))
luguhu
2022-08-07 19:07:15 +08:00
用 unsafe.Sizeof(reflect.TypeOf(stu.s)) 才对
Trim21
2022-08-07 19:12:12 +08:00
直接用 unsafe.Offset…
Trim21
2022-08-07 19:14:23 +08:00
unsafe.Offset(Stu{}.s) 就是 s 的 offset 了。你这样手动拼接出来的不一定对。如果编译器做了 align 的话用 size 是没法得到正确结果的。
Trim21
2022-08-07 19:17:09 +08:00
@luguhu reflect.TypeOf(Stu{}).Filed(3).Offset)
luguhu
2022-08-07 19:35:06 +08:00
@Trim21 我发现获取不到指针可能不是 offset 的问题, 因为获取到的 st1 的 offset 是 48, 但是指针要再 + 16 才能获取到
Trim21
2022-08-07 19:44:13 +08:00
@luguhu #6 有两个问题,一个是这样的 offset 可能是错的,另一个是你 st1 解引用的时候类型错了,应该用 *(**Stu)(unsafe.Add(p, unsafe.Offsetof(Stu{}.st1)))

https://go.dev/play/p/GsBLT4ENqN-

然后还有一个潜在问题,反射包里有一个未导出的方法 reflect.ifaceIndir ,如果一个结构体是 direct 的时候指针字段(包括 map 和 slice 等)还会各种奇怪的行为...
luguhu
2022-08-07 19:52:45 +08:00
@Trim21 确实是这样

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/871263

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX