你使用的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
8条答案
按热度按时间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)
qxsslcnc2#
也许list.List应该禁用复制功能,位于go/src/sync/cond.go的第94行。
| | typenoCopystruct{} |
wfauudbj3#
是的,我知道为什么会发生这种情况,谢谢你。无论如何,关于
List
的评论告诉了The zero value for List is an empty list ready to use.
。eagi6jfj4#
是的,我知道为什么会发生这种情况,谢谢你 :) 无论如何,关于
List
的评论表明The zero value for List is an empty list ready to use.
是零值。当你重新分配它时,但在你调用 Remove 之后,它的长度变为 -1(从空列表中删除一个元素)。vxbzzdmp5#
Change https://golang.org/cl/233326 mentions this issue:
container/list: check the list state before mutation
am46iovg6#
/cc @griesemer
jq6vz3qz7#
我确认上面的代码是可重现的。重置列表不会改变指向列表的指针。元素仍然指向原始列表。Remove()函数检查指向列表的指针是否与元素中的列表指针相同。
dtcbnfnu8#
重置列表不会改变指向列表的指针。这似乎也可能导致内存泄漏。