6

I am struggling to understand exactly what is happening when you return a new object from a function in go.

I have this

func createPointerToInt() *int {
    i := new(int)
    fmt.Println(&i);
    return i;
}

func main() {
    i := createPointerToInt();
    fmt.Println(&i);
}

The values printed returned are

0x1040a128
0x1040a120

I would expect these two values to be the same. I do not understand why there is an 8 byte difference.

In what I see as the equivalent C code:

int* createPointerToInt() {
    int* i = new int;
    printf("%#08x\n", i);
    return i;
}

int main() {
    int* r = createPointerToInt();
    printf("%#08x\n", r);
    return 0;
}

The address returned is the same:

0x8218008
0x8218008

Am I missing something blindingly obvious here? Any clarification would be greatly appreciated!

3 Answers 3

7

You are printing the address of the pointer here fmt.Println(&i);. Try this:

func main() {
    i := createPointerToInt();
    fmt.Println(i); //--> Remove the ampersand
}

i is the pointer returned from createPointerToInt - while &i is the address of the pointer you are trying to print. Note in your C sample you are printing it correctly:

printf("%#08x\n", r);
                 ^No ampersand here
Sign up to request clarification or add additional context in comments.

2 Comments

A of course! What a fool, thank you! I should have known that :P I think I was getting confused as go doesn't require you to deference the pointer when you use it like (*object).function or object->function in C, so I thought taking the address there would be the address of the pointer, not the pointer itself. Thanks!
A small addendum to this, and I think why I was initially getting confused. if you create a custom type (type MyType struct { }) and use that instead of int, when you use Println, you get '&{}' output, not the address. For a custom object do you know how to get the address to print?
2

Change &i to i. You are printing address of i while you should print the value of i.

func createPointerToInt() *int {
     i := new(int)
     fmt.Println(i);
     return i;
}

func main() {
    i := createPointerToInt();
    fmt.Println(i);
}

1 Comment

Hi there, small update to this and one of the reasons why I think I'd tried to use the ampersands in the wrong place is when using a custom object (type Example struct {}) using fmt.Println produces &{} not a memory address. Is there a way to force fmt.Println to convert that to a memory address?
0

But how come in your original code the addresses of the two pointers (not memory addresses the pointers are pointing too) are different?

func main() {
    i := createPointerToInt();
    fmt.Println(&i);
}

Is equivalent to:

func main() {
    var i *int  // declare variable i
    i = createPointerToInt(); // assign value of
                              // a different i that was 
                              // declared and initialized
                              // inside the function
    fmt.Println(&i);
}

Edit:

To print the address of a struct you need to use:

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

golang.org/pkg/fmt/

For example:

goplayground

4 Comments

In the original code the first block was the function and the second was main calling that function. The address being returned was that of the local variable pointer in each case, not the address to the region in memory the pointer was referring to. The reason I made this mistake in the first place is in the online golang tool, when you use a custom type (one you create) and use that in place of int in the example, &{} is printed to the console, not an address, which seemed kind of odd, and I'm not sure how to force an address to print
Yes, yes, I was actually talking about the addresses of the two pointers in the original example. Maybe it is too obvious for most people, but it had me confused at first.
@Tom, You need to use printf to print address of a struct, I updated my answer.
Awesome that's just what I was looking for :) Thank you! Much appreciated! @Akavall

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.