Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

container/list: the last Element is changed when use array append #31404

Closed
sxyluanhai opened this issue Apr 11, 2019 · 6 comments
Closed

container/list: the last Element is changed when use array append #31404

sxyluanhai opened this issue Apr 11, 2019 · 6 comments

Comments

@sxyluanhai
Copy link

sxyluanhai commented Apr 11, 2019

What version of Go are you using (go version)?

go version go1.12.3 linux/amd64

Does this issue reproduce with the latest release?

YES

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/sxy/workspace"
GOPROXY=""
GORACE=""
GOROOT="/home/sxy/go"
GOTMPDIR=""
GOTOOLDIR="/home/sxy/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build635210007=/tmp/go-build -gno-record-gcc-switches"

What did you do?

my code

package main

import (
"container/list"
"fmt"
)

func main() {
arr := []int{1,2,3,4}
result := getSubset(arr)

head := 5
for i:=result.Front();i!=nil;i=i.Next() {
    tmp := i.Value.([]int)
    fmt.Println("Begin : " , i.Next())
    tmp = append(tmp,head)
    fmt.Println("End : " , i.Next())
    
}

}

func getSubset(arr []int) (sresult *list.List) {
result := list.New()
if len(arr) == 0 {
b := []int{}
result.PushBack(b)
return result
}
head := arr[0]
subarr := arr[1:len(arr)]

sub := getSubset(subarr)
for i:=sub.Front();i!=nil;i=i.Next() {
    var tmp = i.Value.([]int)
    result.PushBack(tmp)
   
    tmp = append(tmp,head)
    result.PushBack(tmp)
}
return result

}

Output is :

Output
Begin :  &{0xc042066600 0xc0420665a0 0xc0420661e0 [1]}
End :  &{0xc042066600 0xc0420665a0 0xc0420661e0 [1]}
Begin :  &{0xc042066630 0xc0420665d0 0xc0420661e0 [2]}
End :  &{0xc042066630 0xc0420665d0 0xc0420661e0 [2]}
Begin :  &{0xc042066660 0xc042066600 0xc0420661e0 [2 1]}
End :  &{0xc042066660 0xc042066600 0xc0420661e0 [2 1]}
Begin :  &{0xc042066690 0xc042066630 0xc0420661e0 [3]}
End :  &{0xc042066690 0xc042066630 0xc0420661e0 [3]}
Begin :  &{0xc0420666c0 0xc042066660 0xc0420661e0 [3 1]}
End :  &{0xc0420666c0 0xc042066660 0xc0420661e0 [3 1]}
Begin :  &{0xc0420666f0 0xc042066690 0xc0420661e0 [3 2]}
End :  &{0xc0420666f0 0xc042066690 0xc0420661e0 [3 2]}
Begin :  &{0xc042066720 0xc0420666c0 0xc0420661e0 [3 2 1]}
End :  &{0xc042066720 0xc0420666c0 0xc0420661e0 [3 2 1]}
Begin :  &{0xc042066750 0xc0420666f0 0xc0420661e0 [4]}
End :  &{0xc042066750 0xc0420666f0 0xc0420661e0 [4]}
Begin :  &{0xc042066780 0xc042066720 0xc0420661e0 [4 1]}
End :  &{0xc042066780 0xc042066720 0xc0420661e0 [4 1]}
Begin :  &{0xc0420667b0 0xc042066750 0xc0420661e0 [4 2]}
End :  &{0xc0420667b0 0xc042066750 0xc0420661e0 [4 2]}
Begin :  &{0xc0420667e0 0xc042066780 0xc0420661e0 [4 2 1]}
End :  &{0xc0420667e0 0xc042066780 0xc0420661e0 [4 2 1]}
Begin :  &{0xc042066810 0xc0420667b0 0xc0420661e0 [4 3]}
End :  &{0xc042066810 0xc0420667b0 0xc0420661e0 [4 3]}
Begin :  &{0xc042066840 0xc0420667e0 0xc0420661e0 [4 3 1]}
End :  &{0xc042066840 0xc0420667e0 0xc0420661e0 [4 3 1]}
Begin :  &{0xc042066870 0xc042066810 0xc0420661e0 [4 3 2]}
End :  &{0xc042066870 0xc042066810 0xc0420661e0 [4 3 2]}
Begin :  &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 1]}
End :  &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 5]}
Begin :  nil
End :  nil

What did you expect to see?

i expect to get
Begin : &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 1]}
End : &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 1]}

What did you see instead?

why i get
Begin : &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 1]}
End : &{0xc0420661e0 0xc042066840 0xc0420661e0 [4 3 2 5]}

when i use append,the last element has changed.

@hengwu0
Copy link
Contributor

hengwu0 commented Apr 11, 2019

That's because the slice‘s capacity is extended with 2,4,8... and the slice will not extend cap if enough capacity.

1		var tmp = i.Value.([]int)
2		result.PushBack(tmp)

3		tmp = append(tmp, head)
4		result.PushBack(tmp)

when 1:tmp is [4, 3, 2], the cap is 4 actually. Then 3:tmp become [4, 3, 2, 1], and it pushed into result. But if you append the 1:tmp in main(), then the 3:tmp will be changed automaticly.
P.S. 1:tmp means the tmp var in line 1.

@sxyluanhai
Copy link
Author

@hengwu0
--------if you append the 1:tmp in main(), then the 3:tmp will be changed automaticly.
Q: 1:tmp is [4,3,2],the cap is 4;length is 3. append(tmp,5) then get [4,3,2,5],the length is 4,cap is 4. the cap is 4 in this append. cap not changed.Why 3:tmp will be changed automaticly?
i know 1:tmp and 3:tmp point to the same address.Why only the last tmp has changed

@hengwu0
Copy link
Contributor

hengwu0 commented Apr 11, 2019

@hengwu0
--------if you append the 1:tmp in main(), then the 3:tmp will be changed automaticly.
Q: 1:tmp is [4,3,2],the cap is 4;length is 3. append(tmp,5) then get [4,3,2,5],the length is 4,cap is 4. the cap is 4 in this append. cap not changed.Why 3:tmp will be changed automaticly?
i know 1:tmp and 3:tmp point to the same address.Why only the last tmp has changed

because slice‘s default capacity is 1, 2, 4, 8...

@sxyluanhai
Copy link
Author

@hengwu0
--------if you append the 1:tmp in main(), then the 3:tmp will be changed automaticly.
Q: 1:tmp is [4,3,2],the cap is 4;length is 3. append(tmp,5) then get [4,3,2,5],the length is 4,cap is 4. the cap is 4 in this append. cap not changed.Why 3:tmp will be changed automaticly?
i know 1:tmp and 3:tmp point to the same address.Why only the last tmp has changed

because slice‘s default capacity is 1, 2, 4, 8...

Sorry,i can not understand capaccity will affect the tmp`s change
My output shows only the last one [4 3 2 1] changed [4 3 2 5],the others do not change.

@bcmills bcmills changed the title container/list the last Element is changed when use array append container/list: the last Element is changed when use array append Apr 11, 2019
@bcmills
Copy link
Contributor

bcmills commented Apr 11, 2019

For usage questions, see the venues in https://golang.org/wiki/Questions. It's not obvious that anything in container/list is working incorrectly in this example.

Please note that code snippets filed to the issue tracker should generally be links to runnable, properly-formatted examples on https://play.golang.org.

@ianlancetaylor
Copy link
Contributor

This doesn't have anything to do with container/list. It is just how slices and append work. See https://blog.golang.org/slices.

@golang golang locked and limited conversation to collaborators Apr 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants