dongpeng8994 2016-10-10 05:59
浏览 58

扩展切片的大小以防止切片边界超出范围错误

I have written the following:

func main() {
    //inside main        
        fileInputBytes, err := ioutil.ReadFile("/tmp/test")
        byteSize2 := len(fileInputBytes)

        var inputFileByteSlice = fileInputBytes[0:]
        var numberOfIndexes = math.Floor(float64(byteSize / indexingOffset))

        for i := 1; i <= int(numberOfIndexes); i++ {
            // adding i to the indexer insures that we use lookahed to ignore previously inserted indexing values
            var v int = (i * indexingOffset) + i
            Insert(&inputFileByteSlice, v+i, indexingByteValue)
            fmt.Println(i)
        }
    }
    //outside main
    //variation of https://blog.golang.org/slices with pointers and such
        func Insert(slice *[]byte, index int, value byte) {
            // Grow the slice by one element.
            (*slice) = (*slice)[0 : len(*slice)+1]
            // Use copy to move the upper part of the slice out of the way and open a hole.
            copy((*slice)[index+1:], (*slice)[index:])
            // Store the new value.
            (*slice)[index] = value
            // Return the result.
        }

The slice bounds out of range error is getting on my nerves. The length of the slice grows outside of the size and overflows, the reason I don't understand is that I thought the call to 'grow' the slice by one element(before copy) will dynamically allocate more space. Since that is not the case, can anyone offer me a better suggestion?

  • 写回答

2条回答 默认 最新

  • douyulv6921 2016-10-10 06:25
    关注

    First of all, a slice is already a reference type. So you don't need to pass its pointer around if you are not going to change its capacity. So your main can be simplified as:

    func main() {
        fileInputBytes, err := ioutil.ReadFile("/tmp/test")
        byteSize2 := len(fileInputBytes)
    
        // No need to use pointer to slice. If you want a brand new slice
        // that does not affect the original slice values, use copy()
        inputFileByteArray := fileInputBytes
        var numberOfIndexes = math.Floor(float64(byteSize / indexingOffset))
    
        for i := 1; i <= int(numberOfIndexes); i++ {
            var v int = (i * indexingOffset) + i
    
            // Insert needs to return the newly updated slice reference
            // which should be assigned in each iteration.
            inputFileByteArray = Insert(inputFileByteArray, v+i, indexingByteValue)
            fmt.Println(i)
        }
    }
    

    Then, the Insert function can be simplified simply by using append along with copy and returning the newly created slice:

    func Insert(slice []byte, index int, value byte) []byte {
        if index >= len(slice) {
            // add to the end of slice in case of index >= len(slice)
            return append(slice, value)
        }
        tmp := make([]byte, len(slice[:index + 1]))
        copy(tmp, slice[:index])
        tmp[index] = value
        return append(tmp, slice[index:]...)
    }
    

    This may not be the best implementation but it is simple enough. Example usage at: https://play.golang.org/p/Nuq4RX9XQD

    评论

报告相同问题?

悬赏问题

  • ¥15 mmocr的训练错误,结果全为0
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀