c++memory-addresspass-by-value

C++ Pass-by-value, shouldn't the memory_addresses of the two variables be copied and binded into different places?


I'm practicing C++, and facing the Pass-by-value/reference topic. What I learned from BroCode is that, when we call a swap function by the parameters' value, both of their memory_addresses will be different from the original ones.

#include <iostream>

using std::cout;
using std::endl;

void swap_byValue(int dog, int cat);
void swap_byReference(int &dog, int &cat);
void print(int dog, int cat);

int main(){
    int dog = 100;
    int cat = 999;

    cout << "*****************************" << endl
         << "*  variable_name  *  value  *" << "      (memory_address)" << endl;

    print(dog, cat);

    swap_byValue(dog, cat);
    print(dog, cat);
    return 0;
}

void swap_byValue(int dog, int cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}
void swap_byReference(int &dog, int &cat){
    int temp;
    temp = dog;
    dog = cat;
    cat = temp;
}

void print(int dog, int cat){
    cout << "*****************************" << "----->  " << &dog << endl
         << "*       dog       *   " << dog << "   *" <<endl
         << "*****************************" << "----->  " << &cat << endl
         << "*       cat       *   " << cat << "   *" <<endl; 
}

The result after running is down below:

*****************************
*  variable_name  *  value  *      (memory_address)
*****************************----->  0x42295ffc30
*       dog       *   100   *
*****************************----->  0x42295ffc38
*       cat       *   999   *
*****************************----->  0x42295ffc30
*       dog       *   100   *
*****************************----->  0x42295ffc38
*       cat       *   999   *

But shouldn't the memory-address of variable dog(before swapping) differ from variable dog(after swapping)? They're both 0x42295ffc30 right now. Is there anything I misunderstood or did wrong? Thanks a lot.


Solution

  • The results you get are to be expected. It is not possible to change the address of an object. What can be done for example is to copy an object, then you have a new object at a different address and the old object at the same address. A reference on the other hand does not create a new object it merely refers to the original object, hence has the same address.

    Calling void swap_byValue(int dog, int cat) has no effect whatsoever and void swap_byReference(int &dog, int &cat) swaps the values of the parameters. What you should actually be using is std::swap to swap values of two variables.

    The addresses you print in print are those of the function local variables dog and cat. You can avoid confusion by using distinct names:

    void print(int a, int b){
        cout << "*****************************" << "----->  " << &a << "\n"
             << "*       a         *   " << a << "   *\n"
             << "*****************************" << "----->  " << &b << "\n"
             << "*       b       *   " << b << "   *\n"; 
    }
    

    This prints the addresses of the two variables a and b which are copies of the arguments passed to the function. When you call the function twice or more they may happen to end up in the same place in memory. This is possible because after the function returns they are gone.

    If you print the addresses of dog and cat in main you will also see that they do not change after swapping.

    I can only guess what you misunderstood, perhaps you wanted to see this:

    #include <iostream>
    
    void by_value(int x) { std::cout << "by_value: " << &x << "\n"; }
    void by_ref(int& y) { std::cout << "by_ref: " << &y << "\n"; }
    
    int main() {
        int z = 42;
        std::cout << "in main: " << &z << "\n";
        by_value(z);
        by_ref(z);
    }
    

    Possible output:

    in main: 0x7ffca8f5989c
    by_value: 0x7ffca8f5987c
    by_ref: 0x7ffca8f5989c
    

    z in main and y in by_ref do have the same address, because its the same object. y is a reference to z. The address of the reference is that of the original object. x in by_value has a different address because it is a copy.

    What I learned from BroCode is that, when we call a swap function by the parameters' value, both of their memory_addresses will be different from the original ones.

    That is not correct.