go container/list: 零列表值在重置后中断

yxyvkwin  于 6个月前  发布在  Go
关注(0)|答案(8)|浏览(63)

你使用的Go版本是什么( go version )?

$ go version
go version go1.14.2 darwin/amd64

这个问题在最新版本中是否会重现?

是的。

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env
GOHOSTARCH="amd64"
GOHOSTOS="darwin"

你做了什么?

var l list.List
el := l.PushBack(42)
l = list.List{} // Reset the list.
l.Remove(el)
fmt.Println(l.Len())

你期望看到什么?

0

你看到了什么?

-1
lg40wkob

lg40wkob1#

因为另一个赋值语句l = list.List{}永远不会改变l的地址,所以你可以用以下代码打印出l的内存地址:

fmt.Printf("%p\n", &l)
el := l.PushBack(42)
l = list.List{} // Reset the list.
fmt.Printf("%p\n", &l)

qxsslcnc

qxsslcnc2#

也许list.List应该禁用复制功能,位于go/src/sync/cond.go的第94行。
| | typenoCopystruct{} |

wfauudbj

wfauudbj3#

是的,我知道为什么会发生这种情况,谢谢你。无论如何,关于List的评论告诉了The zero value for List is an empty list ready to use.

eagi6jfj

eagi6jfj4#

是的,我知道为什么会发生这种情况,谢谢你 :) 无论如何,关于 List 的评论表明 The zero value for List is an empty list ready to use. 是零值。当你重新分配它时,但在你调用 Remove 之后,它的长度变为 -1(从空列表中删除一个元素)。

vxbzzdmp

vxbzzdmp5#

Change https://golang.org/cl/233326 mentions this issue: container/list: check the list state before mutation

jq6vz3qz

jq6vz3qz7#

我确认上面的代码是可重现的。重置列表不会改变指向列表的指针。元素仍然指向原始列表。Remove()函数检查指向列表的指针是否与元素中的列表指针相同。

dtcbnfnu

dtcbnfnu8#

重置列表不会改变指向列表的指针。这似乎也可能导致内存泄漏。

相关问题