tags:

views:

90

answers:

3

" Double pointers are also sometimes employed to pass pointers to functions by reference " can somebody can explain me the above statement, what exactly does point to function by reference means ?

+2  A: 

It means that you have a function that takes a pointer pointer (type int ** for example). This allows you to modify the pointer (what data it is pointing to) much in the way passing a pointer by reference would allow.

void change (int *p) {*p = 7;}
void Really_Change (int **pp) {*pp = null;}

int p = 1;
int *pp = &p;
// now, pp is pointing to p. Let's say it has address 0x10;

 // this makes a copy of the address of p. The value of &p is still 0x10 (points to p).
 // but, it uses that address to change p to 7.
change(&p);
printf("%d\n", p); // prints 7;


// this call gets the address of pp. It can change pp's value
// much like p was changed above.
Really_Change(&pp);

// pp has been set to null, much like p was set to 7.

printf("%d\n", *pp); // error dereference null. Ka-BOOM!!!

So, in the same way that you can pass a pointer to an int and change the value, you can pass a pointer to a pointer and change its value (which changes what it points to.)

JoshD
Just to clarify English syntax… there is no pointer to a function; the function is what receives a pointer to a pointer of arbitrary type.
Potatoswatter
`cout << *pp << endl; // prints 1;`I think it would print `7`.
Hemant
@Hemant: Yes, I guess I missed that in editing. Thank you.
JoshD
I thought this question was tagged C, no?
Jens Gustedt
`iostreams`, EW
Matt Joiner
@Mat Joiner, @Jens Gustedt: Thanks for pointing this out to me. I've changed the code to use printf.
JoshD
The code is so readable now :) I thort maybe something was wrong with your **bitshifting** keys. ;)
Matt Joiner
@Matt Joiner: What, can't a guy try to shift some undeclared variable seven bits to the left? :)
JoshD
+3  A: 

I believe this example makes it clearer :

//Double pointer is taken as argument
void allocate(int** p,  int n)
{
    //Change the value of *p, this modification is available outside the function
    *p = (int*)malloc(sizeof(int) * n);
}

int main()
{

    int* p = NULL;

    //Pass the address of the pointer
    allocate(&p,1);

    //The pointer has been modified to point to proper memory location
    //Hence this statement will work
    *p=10;

    //Free the memory allocated
    free(p);

    return 0;
}
Naveen
Your example doesn't require double pointers and it doesn't use a function pointer either.
Fredrick Pennachi
It was just to demonsrate how double pointers work. The question is not about function pointers so it doesn't cover it.
Naveen
Sorry, I misunderstood the question. If you edit your answer slightly I can cancel my -1, otherwise it says my vote is locked in :(
Fredrick Pennachi
@Fredrick Pennachi: Edited :-)
Naveen
@Naveen: Done :)
Fredrick Pennachi
A: 

I'll try to explain with both code and plain english :). The explanation may get long, but it will be worth the while.

Suppose we have a program, running its main() function, and we make a call to another function that takes an int parameter.

Conceptually, When you pass a variable as a parameter to a function, you can do so in (roughly speaking) two ways: by value, or by reference.

"By value" means giving the function a copy of your variable. The function will receive its "content" (value), but it won't be able to change the actual variable outside its own body of code, because it was only given a copy.

"By reference", on the other hand, means giving the function the actual memory address of our variable. Using that, the function can find out the variable's value, but it can also go to that specified address and modify the variable's content.

In our C program, "by value" means passing a copy of the int (just taking int as argument), and "by reference" means passing a pointer to it.

Let's see a small code example:

void foo(int n) {
    n = 10;
    printf("%d\n", n);
}

int main() {
    int n = 5;

    foo(n);
    printf("%d\n", n);

    return 0;
}

What will the output of this program be? 10 10? Nope. 10 5! Because we passed a copy of the int, by value and not by reference, foo() only modified the number stored in its copy, unable to reach main()'s copy.

Now, if we do it this way:

void foo(int* n) {
    *n = 10;
    printf("%d\n", *n);
}

int main() {
    int n = 5;
    foo(&n);
    printf("%d\n", n);

    return 0;
}

This time we gave foo() our integer by reference: it's actual memory address. foo() has full power to modify it by accessing it's position in memory, foo() and main() are working with the same copy, and so the output will be 10 10.

As you see, a pointer is a referece,... but also a numerical position in memory. It's similar to an int, only the number contained inside is interpreted differently. Think of it this way: when we pass our int by reference, we're passing an int pointer by value!. So the same by value/by reference logic can be applied to pointers, even though they already are references.

If our actual variable was not an int, but an int reference (pointer), and we wanted main() and foo() to share the same copy of that reference so that foo() can modifiy it, what would we do? Why of course, we'd need a reference to our reference! A pointer to a pointer. That is:

int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
            Stores int*'s memory address so we can pass int*s by reference. */

I hope this was useful.

Santiago Lezica