Pointers 将局部变量指针传递到Golang中的通道安全吗?

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

我有一个代码块,用于查询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
作为
的输出reflect.TypeOf

我的怀疑是,
由于
GetFromAD()
中定义的
ADElements:=[]ADElement{}
是一个局部变量,必须在堆栈中分配它,并且当
GetFromAD()
退出时,必须销毁堆栈的内容,对
GetFromAD()
的进一步引用必须指向无效的内存引用,然而,我仍然得到了
GetFromAD()
返回的元素的确切数目,没有任何错误。这是怎么回事?这样做安全吗?

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

退房

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

定义“安全”

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

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


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

Go在这里完全不用担心。谢谢@Volker。然而,我想知道它是如何工作的:)
*[]somemodules.ADElement