Chapi
Chapi

Reputation: 85

"foo(int* pointer)" vs. "foo(int* &pointer)"

I'm new to C++ and I'm trying to learn exactly how pointers (*) and references (&) work.

In the following code:

#include <iostream>
using namespace std;


void test1(int* pointer)
{
    int foo = 2;
    pointer = &foo;
}

void test2(int* &pointer)
{
    int foo = 3;
    pointer = &foo;
}

int main()
{
    int aux = 1;
    int* p = &aux;

    test1(p);
    cout << *p << ",";
    test2(p);
    cout << *p << endl;

    system("PAUSE");
}

Which outputs 1,3

Why does test1 manage to change the memory location at which p is pointing to but test1 doesn't?

Since test1 isn't changing p, then what is the line pointer = &foo; doing on test1?

Upvotes: 0

Views: 430

Answers (1)

Ben S.
Ben S.

Reputation: 1143

Pass-by-value vs. pass-by-reference

C++ has two general ways to pass a value to a function - pass-by-value, as in void foo(int i), and pass-by-reference, as in void foo(int &i). Pass-by-value makes a copy of the value that's passed in, whereas pass-by-reference binds a reference to the value that's passed in. As such, a function that uses pass-by-value can't modify the original value, because the function only has a copy, whereas pass-by-reference provides a way to modify the original value through the reference.

In the case of test1, what you're doing is passing a value of a pointer type by value. When you call test1(p), it's as if you did this:

int foo = 2;
pointer = &foo;

As such, p is unchanged.

In the case of test2, you're passing a value of a pointer type by reference, which does produce a change in p. You could actually write the following and it would have the same effect:

int *&pointer = p;
int foo = 3;
pointer = &foo;

Undefined behavior

Note that you typically don't want to take the address of a local variable like foo and assign it to something outside the function, as you're doing in test2. The result of calling test2(p) is that p points to an object that no longer exists, so any attempt to read from p would produce what's called "undefined behavior" - basically, the computer may have reused the memory that had been used to store foo during the execution of test2, and you could get a very strange value if you try to read from p.

In your example results, *p is 3, which looks reasonable, but that's just one possibility. The value could also have been 0, -100, or any other int value, and different compilers, different platforms, or even different runs of the program on the same machine might give a different answer. By accessing the value of a dead object, the program steps outside the bounds of normal C++ - at that point, all bets are off and pretty much anything could theoretically happen.

Upvotes: 3

Related Questions