Pointers and references – part 2

As a follow on from the part 1 – pointers and references – this tutorial is all about how to pass pointers and references, with usage in functions.

As shown in the previous tutorial, a pointer is just a point to another memory location where the data is actually stored and a reference/address is the address (memory) location of a variable. e.g.

int *pInt= NULL;
int intValue = 10;
pInt = &intValue;

Here the pointer (*pInt) is first set to NULL, to point to no where in memory because it may have a rogue data in there and you would not want that. Then the intValue variables is set to 10 and then pInt value is set to the memory (address/reference) location of intValue.

When passing a parameter to a normal function you are just passing a copy of the value and not the actual variable being passed, so that if you make any alternations to that parameter variable is it not reflected back into the variable that was actual passed. I have included code at the bottom with the output that displays the memory locations of the local (function variables parameters) and the parameters passed and you can see that the memory location is different in the standard copy-value function (normalReturnMethod).

So for a coding example

int normalReturnMethod(int value)
{
    value = value +2;
    return (value);
}
 
int intValue = 10;
 
int newValue = normalReturnMethod(intValue);
cout << "new Value :  " << newValue << " intValue  : " << intValue;

and the output would be

new Value = 12 int Value : 10

Because even though in the function we are incrementing the variable value, it has not direction relationship with the intValue that was passed to it.

But if you did a pointer (*) in the parameters of the function, then the actual variable memory location is passed and not just a copy of the variable, in which case you can alter the variable.

For example in code

void pointerReturnMethod(int *pValue)
{
    // increment the value pointed to in the pValue parameter
    *pValue +=2;
}
int intValue = 10;
pointerReturnMethod(&intValue);
cout << "intValue = " << intValue;

and the output would be

intValue = 12

Because the function is talking to the parameter variable passed, instead of just a copy and you can do anything on that parameter as you would normally.

The other method is by passing a reference to the function instead of a address (memory) location or copy-of-value, this one is slightly more fun, because since you do not alter the way that you knowing are passing the variable e.g. passing in the memory location with the &, then you could think it is just the copy-of-value function and it may alter the passing variable as well, which really is not a good thing.

Code example

void referenceReturnMethod(int &fValue)
{
    fValue +=4;
}
 
int intValue = 10;
referenceReturnMethod(intValue);
cout << "intValue = " << intValue;

and the output would be

intValue = 14;

which if you was not wanting to pass the reference to the variable to be “worked on” as such, then you may hit some problems with debugging and start to wonder why the variable was alter when passed to a function.

Here is some more code that you can compile up and see what is happening. have fun.!!

#include <iostream>
 
using namespace std;
 
int normalReturnMethod(int value)
{
    cout << "normal Return Method memory location " << &value << endl;
    return (value + 2);
}
 
// pass in the pointer to a variable, the pointer (*)value is the same place 
// instead of a copy as normalReturnMethod parameter
void pointerReturnMethod(int *pValue)
{
    // increment the value pointed to in the pValue parameter
    *pValue +=2;
    cout << "pointer Return Method memory location  " << pValue << endl;
}
 
// pass in the reference to the method in the parameter, the reference is 
// a reference point to the passed in variable e.g. same place.
void referenceReturnMethod(int &fValue)
{
    fValue +=4;
    cout << "reference Return Method memory location " << &fValue << endl;
}
 
int main()
{
    // the standard way to update a value is to return a value
    // this is called the copy-variable way - it copies the value from the passing parameter to the function parameter
    int returnValue = normalReturnMethod(10);
    cout << "Hex value of memory place of returnValue " << &returnValue << endl;
    cout << "The new interger value " << returnValue << endl;
 
    // but if you pass the reference of variable &, this will alter the actually variable instead of needing to 
    // pass the variable back in the return type. - it passes a memory location reference
    pointerReturnMethod(&returnValue);
    // the returnValue has been altered.
    cout << "The new interger value " << returnValue << endl;
 
    referenceReturnMethod(returnValue);
    cout << "The returnvalue updated " << returnValue << endl;
    cout << "The memory address of the reference/pointer functions are the same as the returnValue hex value"<< endl;  
    cout << endl  << endl;
 
    int *valuePointer = &returnValue;
    // the find out the difference * and & here are the values
    cout << "The Hex value of memory place for returnValue and the VALUE of the memory place for the pointer are the same"<< endl;
    cout << "The value of the value pointer " << valuePointer << endl;
    cout << "Hex value of memory place of returnValue " << &returnValue << endl;
    cout << "The actually memory place of the valuepointer " << &valuePointer << " and the POINTED value " << *valuePointer << endl;
    cout << "And of course the valuepointer is the same, because it is pointing to the same place " << *valuePointer << endl;
 
 
    // the pointer (*) is the pointed to memory location. e.g. int value=10 could be a memory location that is pointed to
    // the reference (&) is the memory address of the variable
    // so for a pointer you need to set the memory location of a variable to its value, which in turn its 
    // pointed value is the variable, but its address/reference (&) is always the same becaues that is the place where
    // the pointer variable is setup, but the value (the memory location) is what alters.
    return 0;
}

and my test outputs would be, of course your memory locations will be different.

normal Return Method memory location 0x7fff34d8d1bc
Hex value of memory place of returnValue 0x7fff34d8d1dc
The new interger value 12
pointer Return Method memory location  0x7fff34d8d1dc
The new interger value 14
reference Return Method memory location 0x7fff34d8d1dc
The returnvalue updated 18
The memory address of the reference/pointer functions are the same as the returnValue hex value
 
 
The Hex value of memory place for returnValue and the VALUE of the memory place for the pointer are the same
The value of the value pointer 0x7fff34d8d1dc
Hex value of memory place of returnValue 0x7fff34d8d1dc
The actually memory place of the valuepointer 0x7fff34d8d1d0 and the POINTED value 18
And of course the valuepointer is the same, because it is pointing to the same place 18

2 thoughts on “Pointers and references – part 2”

  1. Java does use pointers under the hood for its memory allocation. But yeah.. java does save allot of hassle when the user does not need to know what is happening under the hood.

Leave a Reply

Your email address will not be published. Required fields are marked *