FAQ
Hi,

I'm trying to convert a slice of arrays into a slice of slices but I
encountered some really weird behavior.

Every value in my copy somehow becomes the last value that was copied as if
the slices suddenly started sharing the same backing array even though they
were originally derived from different arrays.

The only way I can explain is with this example code.

http://play.golang.org/p/gTmh73Hcjp

package main

import "fmt"

func main() {
var original [][1]byte

original = append(original, [1]byte{1})
original = append(original, [1]byte{2})

fmt.Println("ORIGINAL", original)

var loopcopy [][]byte

for _, array := range original {
slice := array[:]
fmt.Println("COPY IN LOOP", slice)
loopcopy = append(loopcopy, slice)
}

fmt.Println("LOOP COPY", loopcopy)

var unrolled [][]byte
fmt.Println("COPY UNROLLED", original[0][:])
unrolled = append(unrolled, original[0][:])
fmt.Println("COPY UNROLLED", original[1][:])
unrolled = append(unrolled, original[1][:])

fmt.Println("UNROLLED COPY", unrolled)
}

I expect the output to be

ORIGINAL [[1] [2]]
COPY IN LOOP [1]
COPY IN LOOP [2]*LOOP COPY [[1] [2]]*
COPY UNROLLED [1]
COPY UNROLLED [2]
UNROLLED COPY [[1] [2]]

but instead I get

ORIGINAL [[1] [2]]
COPY IN LOOP [1]
COPY IN LOOP [2]*LOOP COPY [[2] [2]]*
COPY UNROLLED [1]
COPY UNROLLED [2]
UNROLLED COPY [[1] [2]]

Some how the copy made in the loop contains 2,2 instead of 1,2

I'm using go 1.0.3 locally. When I press the run button in go playground I also see the unexpected behavior.
I was also able to reproduce the behavior with a local build with version "devel +5529ef3e8a9b Wed Dec 12 16:43:54 2012 +0100"

Is this a real issue or have I done something dumb.


--

Search Discussions

  • Jesse McNelis at Dec 12, 2012 at 9:27 pm

    On Thu, Dec 13, 2012 at 8:17 AM, wrote:

    for _, array := range original {
    slice := array[:]
    fmt.Println("COPY IN LOOP", slice)
    loopcopy = append(loopcopy, slice)
    }

    The array variable here is declared for the entire loop, not for each
    iteration.
    You're taking a slice that points to the array variable and then copying
    new values in to that variable on each iteration of the loop. So every
    slice has the same backing array.
    You want:
    for i := range original {
    arr := original[i]
    slice := arr[:]
    fmt.Println("COPY IN LOOP", slice)
    loopcopy = append(loopcopy, slice)
    }




    --
    =====================
    http://jessta.id.au

    --
  • Steven Pearson 78 at Dec 12, 2012 at 9:37 pm
    Hi Jesse,

    Turns out I'm just plain old dumb :)

    I couldn't imagine where the "mysterious" common backing array was coming
    from and I didn't consider that the array declared in the loop was really a
    "re-used" copy that I was slicing.

    Thanks for you help.

    Steve.

    On Wednesday, 12 December 2012 22:27:19 UTC+1, Jesse McNelis wrote:

    On Thu, Dec 13, 2012 at 8:17 AM, <steven.p...@gmail.com <javascript:>>wrote:
    for _, array := range original {
    slice := array[:]
    fmt.Println("COPY IN LOOP", slice)
    loopcopy = append(loopcopy, slice)
    }

    The array variable here is declared for the entire loop, not for each
    iteration.
    You're taking a slice that points to the array variable and then copying
    new values in to that variable on each iteration of the loop. So every
    slice has the same backing array.
    You want:
    for i := range original {
    arr := original[i]
    slice := arr[:]
    fmt.Println("COPY IN LOOP", slice)
    loopcopy = append(loopcopy, slice)
    }




    --
    =====================
    http://jessta.id.au

    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 12, '12 at 9:27p
activeDec 12, '12 at 9:37p
posts3
users2
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase