Skip to content

Issue with copying heaps in the "container/heap" interface #74014

Closed as not planned
@cad106uk

Description

@cad106uk

Go version

go version go1.24.2 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/ciaran/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/ciaran/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2688572856=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/ciaran/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/ciaran/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/ciaran/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.2'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Set up a heap of rune using the "container/heap" . I made a heap of runes origin then made a copy of origin using the := syntax (copy_of_origin). I then used heap.Remove(&copy_of_origin, 3) and origin was reordered

(the type runeHeap was setup using by type runeHeap []rune and making the interface methods Len, Less, Swap, Push and Pop)

eg

func main() {
	var1 := runeHeap{'T', 'h', 'i', 's', 'i', 's', 'a', 't', 'e', 's', 't'}
	heap.Init(&var1)
	for idx, val := range var1 {
		fmt.Println()
		fmt.Println("STUB:2 var1", string(var1))
		var2 := var1
		// var1 and var2 are the same
		fmt.Println("STUB:2 var1", string(var1), string(var2))
		val1 := heap.Remove(&var2, idx).(rune)
		// var1 has now been reordered
		fmt.Println("STUB:2 var1", string(var1), string(var2))
	}
}

This problem does not happen when i use the copy function

func main() {
	var1 := runeHeap{'T', 'h', 'i', 's', 'i', 's', 'a', 't', 'e', 's', 't'}
	heap.Init(&var1)
	for idx, val := range var1 {
		fmt.Println("STUB:2 var1", string(var1))
		var2 := make(runeHeap, var1.Len())
		copy(var2, var1)
		// var1 and var2 are the same
		fmt.Println("STUB:2 var1", string(var1), string(var2))
		val1 := heap.Remove(&var2, idx).(rune)
		// var1 has not been changed this time.
		fmt.Println("STUB:2 var1", string(var1), string(var2))
	}
}

What did you see happen?

When I made a copy of an array that implemented the heap and the use the heap.Remove function on the copy, the original heap I had copied from was rearrange. This only happened when I copied the heap using the := syntax. When I used the copy function to copy the heap, the original was unaffected by running change on the copy

What did you expect to see?

I expected the copying the heap to work the same whether I used the := syntax or the copy method. Changes made to the copy, even when using the heap.Remove function should have no effect on the original heap I was copying from.
(I hope my code snippets in the first box show what I am talking about)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions