Есть ли выделение фрагментов в памяти Go? - PullRequest
1 голос
/ 18 марта 2019

Цель: у меня большой буфер, и я хотел бы иметь массив / фрагмент указателя, указывающего на другое местоположение в буфере.

Что я делаю:

datPtrs := make([][]byte, n)
for i:=0; i<n; i++{
    datPtrs[i] = bigBuf[i*m:(i+1)*m]
}

Мой вопрос:

  1. Будет ли это копировать память? Мое предположение нет, но я не могу найти нигде, чтобы подтвердить это.
  2. Каков наилучший способ / инструмент, чтобы узнать, есть ли копия памяти или нет?

Ответы [ 2 ]

3 голосов
/ 18 марта 2019

Срезы Go реализованы в виде структуры:

src/runtime/slice.go:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

Вы назначаете / копируете структуру слайса, которая не копирует базовый массив, только его указатель.


Простая иллюстрация:

package main

import (
    "fmt"
)

func main() {
    buf := make([]byte, 8)
    for i := range buf {
        buf[i] = byte(i)
    }
    sub := buf[1:3]
    fmt.Println(buf)
    fmt.Println(sub)
    for i := range sub {
        sub[i] += 43
    }
    fmt.Println(buf)
    fmt.Println(sub)
}

Детская площадка: https://play.golang.org/p/4OzPwuNmUlY

Вывод:

[0 1 2 3 4 5 6 7]
[1 2]
[0 44 45 3 4 5 6 7]
[44 45]

См. Блог Go: Go Slices: использование и внутреннее оборудование ,

2 голосов
/ 18 марта 2019
  1. Нет

Срез - это просто указатель на память + len и cap
см .: Почему я не могу дублировать срез с помощью `copy () `на Голанге?


Вроде так:
package main

import (
    "fmt"
)

func main() {
    bigBuf := []byte{1, 2, 3, 4, 5}

    datPtrs := make([][]byte, 2)
    for i := 0; i < 2; i++ {
        datPtrs[i] = bigBuf[i : i+1]
    }
    fmt.Println(bigBuf) // [1 2 3 4 5]
    datPtrs[0][0] = 10
    fmt.Println(bigBuf) // [10 2 3 4 5]

    datPtrs[1][0] = 20
    fmt.Println(bigBuf) // [10 20 3 4 5]
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...