Question

First of all, I am slightly hungover so I'm not sure how to formulate this question. Feel free to edit the title or the content to provide better insight.

I have two methods below. Both of them print the address of a pointer. However the addresses are different. When printing the pointers address in the main function the result is exactly the same as passing the pointers address to a function and printing. But when passing the pointer to a function and printing the address, you get a different address. Why is this?

I have understood that when passing variables to functions it copies the values and allocates new memory. But why doesn't it do this for pointer's addresses?

void print_pointer_1(int** p)   {
    printf("In print_pointer_1 address is : \t\t\t%p\n", p);
}

void print_pointer_2(int* i)    {
    printf("In print_pointer_2 address is : \t\t\t%p\n", &i);
}

int main()        {
    int j = 1;
    int* i = &j;

    printf("Directly printing the pointers address in main : \t%p\n", &i);
    print_pointer_1(&i);
    print_pointer_2(i);

    return 0;
}

Produces these outputs:

Directly printing the pointers address in main :    0x7fff24330a48

In print_pointer_1 address is :                     0x7fff24330a48

In print_pointer_2 address is :                     0x7fff24330a28
Was it helpful?

Solution

void print_pointer_2(int* i)    {
                          ^
                 Here is the local variable, you're
                 printing the address of this local variable.
    printf("In print_pointer_2 address is : \t\t\t%p\n", &i);
}

So you're just printing the address of a local variable. You would rather print the value of the pointer, as that pointer stores the address you assigned to it in main()

    printf("In print_pointer_2 address is : \t\t\t%p\n", i);

This will naturally print the address of j, not the address of your i variable in main, as your print_pointer_1() function does. print_pointer_2() has no way of knowing the address of main()'s i

OTHER TIPS

Firstly, why not the much simpler:

void print_pointer (void *p) {
    printf("In print_pointer address is : \t\t\t%p\n", p);

}

To the question: print_pointer_1 takes a pointer as an argument (a pointer that happens to point to a pointer to an int), which comes in as a parameter. You then print that pointer. So far so good. But the pointer you are printing is the address of the local variable i, which has no link to j (only its contents have a link to j, not the address). However, this explains why it's the same as the address as directly printed in main(), as they are both the address of i.

print_pointer_2 takes a pointer as an argument (a pointer that happens to point to a pointer to an int), which comes in as a parameter. However, uou then print the address of that pointer, which will be an address in the stack frame of print_pointer_1 - an address which is no use to you. It's not the address of anything in main(). You're calling this with i as the parameter, but it wouldn't matter what you call it with; it would always print the same address as it's the address of the parameter your are printing.

Ok lets try to explain it like this. I use "mem j" to mean memory allocated to store the value of variable j. That is the memory you access when you use "j". You will get the value stored at this memory location.

So in main

mem j <- contains 1

mem i <- contains address of mem j

you call "print_pointer_1(&i)", which means you give "print_pointer_1" the value "address of mem i" as parameter.

In print_pointer_1 you will then print the value "address of mem i".

you then call "print_pointer_2(i)". Since i contains "address of mem j", this is the value you pass to "print_pointer_2".

Now to make this simpler, let's for a second use this implementation for "print_pointer_2":

void print_pointer_2(int* myvalue)    {
    printf("In print_pointer_2 address is : \t\t\t%p\n", &myvalue);
}

So you print "address of mem myvalue" which has nothing to do with "address of mem i". So of course "print_pointer_2" prints something different than "print_pointer_1" ;-).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top