What is the difference between passing the pointer to a function vs passing the address of the pointer to the function?

If I create a pointer in main I can pass it to a function by just passing the pointer or I can pass the address of the pointer, but what's the difference.

I know in example 1 I pass the address of a pointer (*a), so the variable type inside the function (**pA) has to be a pointer that's pointing to another pointer that's pointing to an int, that's why the two asterisks.

In example 2 I pass the address of where the int is stored (b), so the variable inside the function is just a pointer pointing to an int.

So in example 1 we have a pointer pointing to another pointer pointing to an int. In example 2 we have two separate pointers pointing to the same int. Is this correct? If so since both of these methods do the same task is one way always better than the other or does it depend on the situation?


example 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void function(int **pA){
  **pA += 1;
  std::cout<<**pA <<std::endl;
}

int main(){
  int *a = new int;
  *a=5;
  function(&a);
  std::cout<<*a <<std::endl;

  delete a;

  return 0;
}


example 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void function(int *pB){
  *pB += 1;
  std::cout<<*pB <<std::endl;
}

int main(){
  int *b = new int;
  *b=5;
  function(b);
  std::cout<<*b <<std::endl;

  delete b;

  return 0;
}
yes, you are correct.

modern code does not use a lot of pointers, so in practice, neither function is of much value for most situations. If you have some specific need to accept and handle pointers, then it depends on what you have and the requirements of your function (your design should say explicitly what the arguments to your function are, and that governs what is passed into it).

double pointers to a single thing is usually wasteful. Normally ** is used for a 2-d construct, on par with int[10][20]. When both dimensions of the ** are allocated as blocks, it becomes a 2-d construct. I dislike ** and vectors of vectors and prefer to keep things *physically in ram* as a 1-d block as much as I can, though.

there are no references in C, so if a function needed to modify the value of a variable you need to pass the address of that variable
for example
1
2
3
4
5
void increment(int *x){
   ++(*x);
}
int value = 42;
increment(&value);
because a pointer is like any other variable, if you want to modify its value you'll pass its address to the function
1
2
3
4
5
6
void increment(int **x){
   ++(*x);
}
int array[42];
int *it = array;
increment(&it);



in your example 1, asking for a int ** is simple obfuscation. (even more considering that's C++ code)
So in example 1 we have a pointer pointing to another pointer pointing to an int. In example 2 we have two separate pointers pointing to the same int.

Yes. Your
Example 1 has by reference semantics. The function refers to caller's variable with a pointer.
Example 2 has by value semantics. The function makes a copy from the caller's variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void val( T x ) { // by value
  x += 42; // modifies local copy
}

void ptr( T* x ) { // by reference, with pointer, C
  *x += 42; // modifies caller's variable
}

void ref( T& x ) { // by reference, with reference, C++
  x += 42; // modifies caller's variable
}

int main() {
  T a = ...
  val( a );
  ptr( &a );
  ref( a );
}


If you need to modify caller's variable, then by reference is good option, although it is also possible to:
1
2
3
4
5
6
7
T val( T x ) {
  x += 42; // modifies local copy
  return x;
}

T a = ...
a = val( a ); // modify a 


If you want to avoid making a copy, but do not want the function to modify your value, then const ref is an option:
void funcl( const T& x );
Last edited on
Topic archived. No new replies allowed.