canadadry
canadadry

Reputation: 8443

Why are addresses of pointers to a WaitGroup different in this golang snippet?

Code snippet on playground

I am printing the pointer address for sync.WaitGroup and they are all different. Why?

func Run() *sync.WaitGroup {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Printf("goroutine %p\n", &wg)

        time.Sleep(5 * time.Second)
        fmt.Println("wokeup")
    }()

    fmt.Printf("returning %p\n", &wg)
    return &wg
}

func main() {
    runtime.GOMAXPROCS(3)
    wg := Run()

    fmt.Printf("     main %p\n", &wg)
    wg.Wait()
}

Typical output shows that the address is diff between that inside the function Run and main. I'd expect that to be the same, n'est-ce pas ?

returning 0xc0840045c0
     main 0xc084000038
goroutine 0xc0840045c0
wokeup

Upvotes: 0

Views: 1275

Answers (2)

peterSO
peterSO

Reputation: 166569

For example,

package main

import "fmt"
import "sync"
import "time"
import "runtime"

func Run() *sync.WaitGroup {
    var wg sync.WaitGroup
    wg.Add(1)
    go func() {
        defer wg.Done()
        fmt.Printf("goroutine %p\n", &wg)
        fmt.Println("sleep for 5s")
        time.Sleep(5 * time.Second)
        fmt.Println("wokeup")
    }()
    fmt.Printf("returning %p\n", &wg)
    return &wg
}

func main() {
    runtime.GOMAXPROCS(3)
    wg := Run()
    fmt.Printf("     main %p\n", wg)
    wg.Wait()
}

Output:

returning 0x1052e2c0
     main 0x1052e2c0
goroutine 0x1052e2c0
sleep for 5s

Change

fmt.Printf("     main %p\n", &wg)

to

fmt.Printf("     main %p\n", wg)

In main, the variable wg contains the address you want. You are printing the address of the variable that contains the address.

Upvotes: 1

photoionized
photoionized

Reputation: 5232

Well, if you notice, the "returning" print statement and the "goroutine" print statement give the same address. Your "main" print is what is off. Look at the line:

fmt.Printf("     main %p\n", &wg)

What do you notice? You're printing &wg, the address of whatever wg is assigned to.

Now look at the return value of your Run() function, you're returning &wg. A pointer to your first declaration of wg as a variable.

So basically your "main" print is printing the the address of the wg pointer address rather than the pointer address itself... hope that makes sense...

But yeah, changing the line in "main" to

fmt.Printf("     main %p\n", wg)

should work.

Upvotes: 1

Related Questions