我有一个代码块,用于查询 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 编译器将在该函数的堆栈帧中分配函数局部的变量。但是,如果编译器在函数返回后无法证明该变量未被引用,则编译器必须在垃圾收集堆上分配该变量,以避免出现悬空指针错误。此外,如果局部变量非常大,将其存储在堆上而不是堆栈上可能更有意义。
陪伴而非守候
TA贡献1757条经验 获得超8个赞
定义“安全”...
您最终不会释放 的内存ADElements
,因为至少有一个对它的实时引用。
在这种情况下,您应该是完全安全的,因为您只传递切片一次,然后您似乎没有修改它,但在一般情况下,最好通过 a 逐个元素传递它chan ADElement
,以避免对切片(或更具体地说,支持切片的数组)的多次非同步访问。
这也适用于地图,如果您通过频道传递地图,然后继续访问它,您可能会遇到奇怪的问题。
- 2 回答
- 0 关注
- 140 浏览
添加回答
举报
0/150
提交
取消