Pointer manipulation with a return pointer
Just a simple walk through of how pointers work when we have a function with a pointer parameter and a pointer return variable. Full Source down below.
First in our main, we have a variable called aNum that has value 100. Then we have a pointer variable point to the address of our aNum variable.
1 2 |
int aNum = 100; int * numPtr = &aNum; |
It should look like this:
We look at numPtr’s dereference, which should be 100.
1 |
std::cout << "*numPtr is: " << *numPtr << std::endl; |
Anything a pointer dereference, it gets the data value contained by the address that the pointer is pointing to. Thus, since our pointer is pointing to an address that contains the value 100 ( aka aNum ).
numPtr dereference is:100
aNum is now: 100
Also, every variable works like a stack. Every additional variable is pushed onto the top. First In Last Out style.
Now, it gets interesting. We have a function definition for returnFunc:
1 2 3 4 5 6 7 |
int * returnFunc( int * param_IntPtr ) { *param_IntPtr = 45; int * heapVariable = new int(6680); std::cout << "heapVariable address is:" << heapVariable << std::endl; return heapVariable; } |
We see that our function definition has a parameter int pointer that points to an int variable’s address.
This means that when we use this returnFunc function, we must give a parameter. In our case, we must give a parameter that the returnFunc’s integer pointer parameter can point to. When we call our function:
1 |
numPtr = returnFunc(numPtr); |
we must provide an integer pointer data for the function definition’s parameter to point to. We give it integer pointer “numPtr”. (Remember, numPtr is pointing to aNum)
This is what it looks like:
Notice that in our stack, the return variable is there. This means that our returnFunc returns an int pointer. Now, we see that our param_IntPtr, which points to our outside scope’s numPtr, gets dereferenced. That dereference is currently 100. At this point:
numPtr points to aNum.
aNum is 100.
numPtr’s dereference is 100.
param_IntPtr points to whatever numPtr is pointing to (WHICH IS aNum), thus param_IntPtr’s dereference (which is aNum’s value) is 100.
1 2 3 4 5 6 7 |
int * returnFunc( int * param_IntPtr ) { *param_IntPtr = 45; int * heapVariable = new int(6680); std::cout << "heapVariable address is:" << heapVariable << std::endl; return heapVariable; } |
When param_IntPtr dereferences, it takes hold of the data its pointing to, namely, aNum. It changes that value to 45.
1 |
*param_IntPtr = 45; |
Thus, now,
*param_IntPtr, aNum, and *numPtr are all 45 at this point.
Then we have this line:
1 |
int * heapVariable = new int(6680); |
we have a local integer pointer point to a new variable made in the heap with the values 6680.
Then we return the integer pointer (address of the heap variable).
1 |
return heapVariable; |
Now when we go to our main function scope, we see this:
1 |
numPtr = returnFunc(numPtr); |
So hence, our main function integer pointer numPtr points FROM aNum’s address to the heap variable’s address. When we dereference numPtr, we get 6680. When we display numPtr’s address,
it would be the address of the variable in our heap.
Console Output
numPtr dereference is:100
aNum is now: 100
heapVariable address is:0x100103ae0
numPtr address is now:0x100103ae0
numPtr dereference is now:6680
aNum is now: 45
Full Source
1 2 3 4 5 6 7 |
int * returnFunc( int * param_IntPtr ) { *param_IntPtr = 45; int * heapVariable = new int(6680); std::cout << "heapVariable address is:" << heapVariable << std::endl; return heapVariable; } |
1 2 3 4 5 6 7 8 9 10 11 |
int aNum = 100; int * numPtr = &aNum; std::cout << "numPtr dereference is:" << *numPtr << std::endl; std::cout << "aNum is now: " << aNum << std::endl; numPtr = returnFunc(numPtr); std::cout << "numPtr address is now:" << numPtr << std::endl; std::cout << "numPtr dereference is now:" << *numPtr << std::endl; std::cout << "aNum is now: " << aNum << std::endl; |