为了账号安全,请及时绑定邮箱和手机立即绑定

将局部变量的指针传递给 Golang 中的通道是否安全?

将局部变量的指针传递给 Golang 中的通道是否安全?

Go
哔哔one 2021-12-20 10:03:34
我有一个代码块,用于查询 AD 并检索结果并写入通道。func GetFromAD(connect *ldap.Conn, ADBaseDN, ADFilter string, ADAttribute []string, ADPage uint32) *[]ADElement {    searchRequest := ldap.NewSearchRequest(ADBaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, ADFilter, ADAttribute, nil)    sr, err := connect.SearchWithPaging(searchRequest, ADPage)    CheckForError(err)    fmt.Println(len(sr.Entries))    ADElements := []ADElement{}     for _, entry := range sr.Entries{        NewADEntity := new(ADElement) //struct        NewADEntity.DN = entry.DN        for _, attrib := range entry.Attributes {            NewADEntity.attributes = append(NewADEntity.attributes, keyvalue{attrib.Name: attrib.Values})        }        ADElements = append(ADElements, *NewADEntity)    }    return &ADElements}上面的函数返回一个指向[]ADElements.在我的initialrun函数中,我称这个函数为ADElements := GetFromAD(connectAD, ADBaseDN, ADFilter, ADAttribute, uint32(ADPage))fmt.Println(reflect.TypeOf(ADElements))ADElementsChan <- ADElements输出说*[]somemodules.ADElement作为 的输出reflect.TypeOf。我的疑问是,由于ADElements := []ADElement{}定义在GetFromAD()是一个局部变量,它必须在堆栈中分配,当GetFromAD()退出时,堆栈的内容必须被销毁,并且进一步的引用GetFromAD()必须指向无效的内存引用,而我仍然得到GetFromAD()没有任何段错误返回的元素的确切数量。这是如何工作的?这样做安全吗?
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

是的,这是安全的,因为 Go 编译器执行转义分析并在堆上分配此类变量。

存储位置确实对编写高效程序有影响。如果可能,Go 编译器将在该函数的堆栈帧中分配函数局部的变量。但是,如果编译器在函数返回后无法证明该变量未被引用,则编译器必须在垃圾收集堆上分配该变量,以避免出现悬空指针错误。此外,如果局部变量非常大,将其存储在堆上而不是堆栈上可能更有意义。


查看完整回答
反对 回复 2021-12-20
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

定义“安全”...

您最终不会释放 的内存ADElements,因为至少有一个对它的实时引用。

在这种情况下,您应该是完全安全的,因为您只传递切片一次,然后您似乎没有修改它,但在一般情况下,最好通过 a 逐个元素传递它chan ADElement,以避免对切片(或更具体地说,支持切片的数组)的多次非同步访问。

这也适用于地图,如果您通过频道传递地图,然后继续访问它,您可能会遇到奇怪的问题。


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 140 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信