25 de diciembre de 2017

Slices may behave strange

While doing an advent of code exercise I saw an strange bug: 

in a [][]byte when I modified a point [3][10] it also was modified in [0,4].

So the problem was a slices sharing in some way the backup array, but how?

for me was not trivial to know why it was happening because I was using append.

After some coincidences that helped me to find first the bug, and then think in how to resolved.

I found out the problem was my split.

Basically I had this input:
.........
.........
.........
.....#...
...#.....
.........
.........
.........

So I read all and put it in a data[]byte.

then I called byte.Split so I have grid [][]byte

then I add a new column at the end:

for i:=range grid{
   grid[i] = append(grid[i], 46)
}

so when I modified grid[3][10],  grid[0][4] was affected. For me this was a big ? why?

Eventually I realized that if  data was a big array of contiguous memory that contained my input.
so the split what it does was create a two dimensional slice:
grid [][]byte, with data[index:]

So even when I was able to work with grid as a two dimensional slice the backup array was the same. big array from data []byte.

so when I added a new column to the row, in reality I was using a contiguous memory space. which was the same as the beginning of my other row.

So when you use bytes split consider that [][]byte is using the same backup array than the source []byte.

This is an example that shows the issue:
package main

import (
   "bytes"   "fmt")

func main() {
   data := []byte(`hello world`)
   grid := bytes.Split(data, []byte(" "))

   fmt.Printf("%q\n", grid)
   grid[0] = append(grid[0], byte('1')) // Adding 1 to hello   grid[0] = append(grid[0], byte('2')) // adding 2 to hello1
   fmt.Printf("%q\n", grid) // the w was modified}

output:
["hello" "world"]
["hello12" "2orld"]

22 de diciembre de 2017

Slice rotate

There is a good site with golang "slice tricks" and want to add the rotate of a square two dimensional slice. 

for i := 0; i < len(a); i++ {
   for j := i; j < len(a); j++ {
      a[j][i], a[i][j] = a[i][j], a[j][i]
   }
}

Slices may behave strange

While doing an advent of code exercise I saw an strange bug:  in a [][]byte when I modified a point [3][10] it also was modified in [...