Pointers as function arguments in C

If I were to have this code, for example:

int num = 5;
int *ptr = #

What is the difference between the following two functions?

void func(int **foo);
void func(int *foo); 

Where I call the function:

func(&ptr); 

I realize that the former of the two takes a pointer to a pointer as a parameter, while the second takes only a pointer.

If I pass in func(&ptr), I am effectively passing in a pointer. What difference does it make that the pointer points to another pointer?

I believe the latter will give an incompatibility warning, but it seems that the details do not matter so long as you know what you are doing. It seems that perhaps for the sake of readability and understanding the former is a better option (2-star pointer), but from a logical standpoint, what is the difference?


Solution 1:

A reasonable rule of thumb is that you can't exactly change the exact thing that is passed is such a way that the caller sees the change. Passing pointers is the workaround.

Pass By Value: void fcn(int foo)

When passing by value, you get a copy of the value. If you change the value in your function, the caller still sees the original value regardless of your changes.

Pass By Pointer to Value: void fcn(int* foo)

Passing by pointer gives you a copy of the pointer - it points to the same memory location as the original. This memory location is where the original is stored. This lets you change the pointed-to value. However, you can't change the actual pointer to the data since you only received a copy of the pointer.

Pass Pointer to Pointer to Value: void fcn(int** foo)

You get around the above by passing a pointer to a pointer to a value. As above, you can change the value so that the caller will see the change because it's the same memory location as the caller code is using. For the same reason, you can change the pointer to the value. This lets you do such things as allocate memory within the function and return it; &arg2 = calloc(len);. You still can't change the pointer to the pointer, since that's the thing you recieve a copy of.

Solution 2:

The difference is simply said in the operations the processor will handle the code with. the value itself is just a adress in both cases, thats true. But as the address gets dereferenced, it's important for the processor and so also for the compiler, to know after dereferencing, what it will be handling with.