第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

為什么這個(gè) Golang 代碼會(huì)泄漏內(nèi)存中變量的值

為什么這個(gè) Golang 代碼會(huì)泄漏內(nèi)存中變量的值

Go
HUH函數(shù) 2023-07-26 19:37:22
此代碼可能會(huì)泄漏內(nèi)存中變量的值。我想也許fmt.XprintY不會(huì)重置緩沖區(qū),但我的調(diào)試嘗試是徒勞的。package mainimport (    "bytes"    "fmt"    "io"    "text/template")type SecWriter struct {    w io.Writer}func (s *SecWriter) Write(p []byte) (n int, err error) {    fmt.Println(string(p), len(p), cap(p))    // here    tmp := fmt.Sprintln("info{SSSSSSSSSSSSSSSSSSSSSSSSSSS}")    if tmp == ""{}    s.w.Write(p[:64])    return 64, nil}func index() {    exp := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA{{1}}"    b := &bytes.Buffer{}    s := &SecWriter{        w: b,    }    t := template.Must(template.New("index").Parse(exp))    t.Execute(s, nil)    fmt.Println("buf: ", b.String())}func main() {    index()}我的go env:set GOARCH=amd64set GOOS=windows去版本go version go1.12.5 windows/amd64輸出是:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 64 641 1 128buf: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1nfo{SSSSSSSSSSSSSSSSSSSSSSSSSSS}                 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA可以看到,內(nèi)存中變量的部分值:tmp := fmt.Sprintln("info{SSSSSSSSSSSSSSSSSSSSSSSSSSS}")泄漏到緩沖區(qū)。
查看完整描述

3 回答

?
繁華開滿天機(jī)

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超4個(gè)贊

沒有內(nèi)存泄漏,
但有一個(gè)問題p := newPrinter():對initialized的調(diào)用p.fmt.init(&p.buf)返回func Fprint(w io.Writer, a ...interface{}) (n int, err error)空閑內(nèi)存(切片的底層數(shù)組),而沒有將其初始化為零(可能是出于性能原因而未初始化 -我們期望全部為零)。

TL;DR:
兩種解決方案:
1. 解決方法:使用s.w.Write(p)代替s.w.Write(p[:64]),或編輯代碼并將其p[len(p):cap(p)]全部設(shè)置為零(如果您不這樣做或無法觸及第二個(gè)解決方案):

func (s *SecWriter) Write(p []byte) (n int, err error) {

? ? b := p[len(p):cap(p)]

? ? for i := range b {

? ? ? ? b[i] = 0

? ? }

? ? fmt.Println(string(p), len(p), cap(p))

? ? // here

? ? tmp := fmt.Sprintln("info{SSSSSSSSSSSSSSSSSSSSSSSSSSS}")

? ? if tmp == "" {

? ? }

? ? s.w.Write(p[:64])

? ? return 64, nil

}

在 Windows ( C:\Go\src\fmt\format.go) 或 Linux ( /usr/local/go/src/fmt/format.go) 文件中,第 58 行將緩沖區(qū)設(shè)置為全零:

? ? b := (*buf)[:cap(*buf)]

? ? for i := range b {

? ? ? ? b[i] = 0

? ? }

在這個(gè)函數(shù)內(nèi)部:


func (f *fmt) init(buf *buffer) {

? ? b := (*buf)[:cap(*buf)]

? ? for i := range b {

? ? ? ? b[i] = 0

? ? }

? ? f.buf = buf

? ? f.clearflags()

}

應(yīng)用此功能后的代碼輸出:


AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 64 64

1 1 128

buf:? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1

長答案:
您正在觀看超出指定長度的切片數(shù)據(jù),并且允許您查看切片容量的切片數(shù)據(jù)。
您可以將:替換m.Writer.Write(p[:8])為:m.Writer.Write(p),這將使您的代碼正常工作。以下代碼顯示將template.Parse()模板標(biāo)記為 3 部分并調(diào)用my.Write()3 次。這里有趣的部分是第二次調(diào)用顯示my.Write()編譯器生成的具有不同切片容量的切片,該切片未初始化為零,“也許這是一個(gè)無害的小問題”:

如果您想監(jiān)視計(jì)算機(jī)的內(nèi)存,請嘗試以下操作:

package main


import (

? ? "bytes"

? ? "fmt"

? ? "io"

? ? "text/template"

)


func main() {

? ? buf := &bytes.Buffer{}

? ? my := &myWriter{"You", buf}

? ? template.Must(template.New("my").Parse("Hi{{.Name}}Bye.")).Execute(my, my)

? ? fmt.Printf("<<%q>>\n", buf.String())

}

func (m *myWriter) Write(p []byte) (n int, err error) {

? ? fmt.Printf("len=%v cap=%v\t%v %v\n", len(p), cap(p), string(p), p[:cap(p)])

? ? no++

? ? fmt.Println("gen:", no, gen())

? ? m.Writer.Write(p)

? ? // m.Writer.Write(p[:8])

? ? return 8, nil

}


type myWriter struct {

? ? Name string

? ? io.Writer

}


const genLen = 8


func gen() string {

? ? b := [genLen]byte{}

? ? for i := range b {

? ? ? ? b[i] = no

? ? }

? ? return string(b[:])

}


var no = byte(49) //'1'

輸出:


len=2 cap=8 Hi [72 105 0 0 0 0 0 0]

gen: 50 22222222

len=3 cap=64? ? You [89 111 117 58 32 53 48 32 50 50 50 50 50 50 50 50 10 50 32 49 48 53 32 48 32 48 32 48 32 48 32 48 32 48 93 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

gen: 51 33333333

len=4 cap=8 Bye. [66 121 101 46 0 0 0 0]

gen: 52 44444444

<<"HiYouBye.">>

并const genLen = 64嘗試進(jìn)行以下 有趣的更改:cap=64更改cap=128(這是預(yù)期之外的):


輸出:


len=2 cap=8 Hi [72 105 0 0 0 0 0 0]

gen: 50 2222222222222222222222222222222222222222222222222222222222222222

len=3 cap=128? ?You [89 111 117 58 32 53 48 32 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

gen: 51 3333333333333333333333333333333333333333333333333333333333333333

len=4 cap=8 Bye. [66 121 101 46 0 0 0 0]

gen: 52 4444444444444444444444444444444444444444444444444444444444444444

<<"HiYouBye.">>

這些t.Execute(my, my)調(diào)用由模板引擎生成func (m *myWriter) Write(p []byte)。plen=3cap=128


在調(diào)試文件內(nèi)第 230 行的第二個(gè)代碼后/usr/local/go/src/fmt/print.go,它似乎fmt.buffer與length=3, 和cap=128, 在這里:


func Fprint(w io.Writer, a ...interface{}) (n int, err error) {

? ? p := newPrinter()

? ? p.doPrint(a)

? ? n, err = w.Write(p.buf)

? ? p.free()

? ? return

}

調(diào)用p := newPrinter()此處初始化p.fmt.init(&p.buf):


// newPrinter allocates a new pp struct or grabs a cached one.

func newPrinter() *pp {

? ? p := ppFree.Get().(*pp)

? ? p.panicking = false

? ? p.erroring = false

? ? p.wrapErrs = false

? ? p.fmt.init(&p.buf)

? ? return p

}

獲取并返回可用內(nèi)存,而不將其初始化為零。


查看完整回答
反對 回復(fù) 2023-07-26
?
繁星coding

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個(gè)贊

在 Go 中,表達(dá)式s.w.Write(p[:64])可以將切片擴(kuò)展到其長度之外而不會(huì)出現(xiàn)錯(cuò)誤(直到切片的容量)。在本例中,提供的緩沖區(qū)長度僅為 1,但您將其擴(kuò)展為 64(如輸出的第二行所示)。額外的63字節(jié)中的內(nèi)容是未定義的,它恰好是某些方法的輸出fmt

解決方案是檢查切片的長度。如果你想讓切片萬無一失,保證無法看到超出其長度的內(nèi)容,可以使用切片的三索引語法來設(shè)置其容量,例如p = p[::len(p)].


查看完整回答
反對 回復(fù) 2023-07-26
?
汪汪一只貓

TA貢獻(xiàn)1898條經(jīng)驗(yàn) 獲得超8個(gè)贊

如果直接給變量賦值而不是這樣做fmt.Sprintln,變量就不會(huì)泄漏。

代碼: https: //play.golang.org/p/Nz0y_MfDjP1

所以我相信fmt.Sprintln是造成泄漏的原因。該函數(shù)調(diào)用另一個(gè)未導(dǎo)出的函數(shù)newPrinter來獲取 a ,printer而該函數(shù)又維護(hù)它自己的池和緩存。我還不夠深入,但我的猜測是,您手動(dòng)創(chuàng)建的緩沖區(qū)可能會(huì)以某種方式在這里重疊/共享。

(如果我發(fā)現(xiàn)其他內(nèi)容,我會(huì)更新答案)


查看完整回答
反對 回復(fù) 2023-07-26
  • 3 回答
  • 0 關(guān)注
  • 198 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號