Passing Pointers

Q.) I did just pass the pointer into the function, and it did work only within the function. In main, the pointers were not swapped.
So, I eventually tried to setup the function as a pass by reference. Now it works perfectly.

So, why is it that I need to pass a pointer by reference?
I thought, a pointer just gets passed in - it is an absolute address so there is not a by value happening. That any change happens to that actual variable pointed to.


When i say, I had to pass it by reference I mean in the function, I had to change it to pass a pointer into the function by reference for the pointers to be swapped in main.
Does anybody have an explanation why this is happening - I do not understand.

Thank you Very Kindly,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
    void Deck::cswap(Deck* &x,Deck* &y)
    //Pointer Args of Deck class
    {
       Deck* temp;
        cout<<"\nSwap Function\n";
        cout<<"x: "<<x<<"\n";
        cout<<"y: "<<y<<"\n\n\n";
       temp=x;
       x=y; y=temp;
        cout<<"x: "<<x<<"\n";
        cout<<"y: "<<y<<"\n";
        cout<<"Swap Completed\n";
     }
//      ***************************************************


   int main()
  {
   Deck poker; // Deck obj
   Deck* ptrA;  // ptr to first element of array
   Deck* ptrB;  // ptr to 10th element of the array
   ptrA=&poker; 
   ptrB=&poker+10;
       cout<<"\n\nFrom Main\n Pointer 1: "<<ptrA<<"\n\n Pointer 2: " 
       <<ptrB<<"\n\n";
   
   poker.cswap(ptrA, ptrB); //Function Call (pasing pntr as args)
       cout<<"\n\n Pointer 1: "<<ptrA<<"\n\n";
   return 0;
  }


After messing around a bit more, I see it is actually a double pointer that is required by that function. So, now I guess the question becomes :

Under what circumstances would I want to be using a double pointer??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Deck::cswap(Deck** x,Deck** y)
    //Pointer Args of Deck class
  {
     Deck** temp;
        cout<<"\nSwap Function\n";
        cout<<"x: "<<x<<"\n";
        cout<<"y: "<<y<<"\n\n\n";
    temp=x;
    x=y; y=temp;
        cout<<"x: "<<x<<"\n";
        cout<<"y: "<<y<<"\n";
        cout<<"Swap Completed\n";
   }
Last edited on
If you don't pass the pointers by reference they will be passed by value which means that the function receives copies of the pointers and changes made to the copies will not affect the original pointers that was passed in from main. Passing the pointers by value would allow you to swap the objects that the pointers point to, but not the pointers themselves.
more words but a repeat of the above:

this is a common misunderstanding with pointers.
think of it this way: a pointer is an integer that holds a number.
if you have this
void foo(int x);
and this
void foo(int &x);
the second one can change the integer x and it changes the input, right?

pointers work the SAME WAY.
void foo( int*x); //the POINTER X CANNOT CHANGE the input parameter. What x points to CAN change, but not X.
void foo(int *&x);//the pointer x CAN CHANGE to point to a different block of memory.

it is only confusing because changes to the pointer's TARGET can be changed without a reference. The target is not the pointer, though, its the target. And it can be changed because if you have something's location in memory, you have it, and if you change it, its changed, and it does not matter that some other part of the code also has that address in hand. You have to understand the difference between the pointer and its target very clearly here.

Last edited on
would that also be the case with an object?
say I have a function in my class kind of like this :
 
void MyClass::myFunction(MyClass x); 

But should it be :
 
void MyClass :: myFunction(MyClass &x);


in order to change the original also??
If by "original" you mean the object that x is a reference to, then yes, pass by reference to change it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Example program
#include <iostream>

class MyClass {
  public:
    MyClass(int a)
    {
        this->a = a;
    }
    
    int a;
};

void foo_val(MyClass x)
{
    std::cout << "This passes MyClass by value (a copy)\n";
    x = MyClass(42);
}

void foo_ref(MyClass& x)
{
    std::cout << "This passes MyClass by reference\n";
    x = MyClass(42);
}

int main()
{
    using namespace std;
    
    MyClass mc(300);
    cout << "Original MyClass: " << mc.a << "\n\n";
    
    foo_val(mc);
    cout << "Original MyClass after foo_val: " << mc.a << "\n\n";
    
    foo_ref(mc);
    cout << "Original MyClass after foo_ref: " << mc.a << "\n\n";
    
}

Original MyClass: 300

This passes MyClass by value (a copy)
Original MyClass after foo_val: 300

This passes MyClass by reference
Original MyClass after foo_ref: 42


Large objects should generally be passed by reference or const reference to avoid unnecessary copies (especially for containers like std::vector).
Last edited on
honestly, if the type is bigger than a pointer (which is usually a system word sized value, eg if you are on a '64 bit computer' its a 64 bit unsigned int) you should always pass by reference, and if you do not change it, make that a constant reference. This saves unnecessary slow copying of large objects; almost all classes should be sent by reference all the time.
Thanks !! I did not know that ...
Last edited on
Topic archived. No new replies allowed.