Pointers 将局部变量指针传递到Golang中的通道安全吗?
我有一个代码块,用于查询AD、检索结果并写入通道Pointers 将局部变量指针传递到Golang中的通道安全吗?,pointers,go,struct,stack,Pointers,Go,Struct,Stack,我有一个代码块,用于查询AD、检索结果并写入通道 func GetFromAD(connect *ldap.Conn, ADBaseDN, ADFilter string, ADAttribute []string, ADPage uint32) *[]ADElement { searchRequest := ldap.NewSearchRequest(ADBaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, fal
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
作为的输出reflect.TypeOf
我的怀疑是,
由于
GetFromAD()
中定义的ADElements:=[]ADElement{}
是一个局部变量,必须在堆栈中分配它,并且当GetFromAD()
退出时,必须销毁堆栈的内容,对GetFromAD()
的进一步引用必须指向无效的内存引用,然而,我仍然得到了GetFromAD()
返回的元素的确切数目,没有任何错误。这是怎么回事?这样做安全吗?是的,它是安全的,因为Go编译器执行转义分析并在堆上分配这样的变量
退房
存储位置确实对编写高效程序有影响。如果可能,Go编译器将在函数的堆栈框架中为函数分配本地变量。但是,如果编译器无法证明函数返回后未引用该变量,则编译器必须在垃圾收集堆上分配该变量,以避免悬空指针错误。此外,如果局部变量非常大,那么将其存储在堆上而不是堆栈上可能更有意义
定义“安全”
您最终不会释放ADElements
的内存,因为至少有一个对它的实时引用
在这种情况下,您应该是完全安全的,因为您只传递一次切片,然后似乎不修改它,但在一般情况下,最好在chan-ADElement
中逐个元素地传递它,以避免对切片(或者更具体地说,支持切片的数组)的多次非同步访问
这同样适用于地图,如果您通过一个频道传递地图,然后继续访问它,您可能会遇到奇怪的问题。Go在这里完全不用担心。谢谢@Volker。然而,我想知道它是如何工作的:)
*[]somemodules.ADElement