简体   繁体   中英

Is it safe to pass pointer of a local variable to a channel in Golang?

I have a code block that queries AD and retrive the results and write to a channel.

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
}

The above function returns a pointer to []ADElements .

And in my initialrun function, I call this function like

ADElements := GetFromAD(connectAD, ADBaseDN, ADFilter, ADAttribute, uint32(ADPage))
fmt.Println(reflect.TypeOf(ADElements))
ADElementsChan <- ADElements

And the output says

*[]somemodules.ADElement

as the output of reflect.TypeOf .

My doubt here is, since ADElements := []ADElement{} defined in GetFromAD() is a local variable, it must be allocated in the stack, and when GetFromAD() exits, contents of the stack must be destroyed, and further references to GetFromAD() must be pointing to invalid memory references, whereas I still am getting the exact number of elements returned by GetFromAD() without any segfault. How is this working? Is it safe to do it this way?

Yes, it is safe because Go compiler performs escape analysis and allocates such variables on heap.

Check out FAQ - How do I know whether a variable is allocated on the heap or the stack?

The storage location does have an effect on writing efficient programs. When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack.

Define "safe"...

You will not end up freeing the memory of ADElements , since there's at least one live reference to it.

In this case, you should be completely safe, since you're only passing the slice once and then you seem to not modify it, but in the general case it might be better to pass it element-by-element across a chan ADElement , to avoid multiple unsynchronized accesses to the slice (or, more specifically, the array backing the slice).

This also holds for maps, where you can get curious problems if you pass a map over a channel, then continue to access it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM