-2

In attempting this HackerRank tutorial (in which you need to set a to a+b and b to |a-b|) I first attempted to modify the pointers to point to the new values:

void update(int *a,int *b) {
    // Complete this function
    int sum = *a + *b;
    int diff = *a - *b;
    if (diff < 0) diff = -diff;
    a = &sum; //these do not work, because a and b are passed by value
    b = &diff;
}

This doesn't work--back in main, a and b point to their original values--because (or so I understand) the pointers a and b are passed into update() by value. No problem, I thought, I'll just change the function signature to pass the pointers by reference:

void update(int *&a,int *&b) {

Sadly, this doesn't work either, but I'm at a loss for why. Can someone explain why these pointers, which appear to be passed by reference, don't get updated outside of the function's scope?

LastStar007
  • 725
  • 1
  • 8
  • 21

2 Answers2

3

It seems like you're already emulating pass by reference for integer variables, by passing them as pointers.

I suspect what you're really supposed to do is

*a = sum;
*b = diff;

Then when calling the function use the address-of operator & to pass pointers to normal int variables:

int sum, diff;
update(&sum, &diff);

If you go with passing references to pointers and do e.g.

a = &sum;

then you will make a point to a local variable. A local variable which will (in a way) cease to exist once the function returns. That means the pointer will be invalid, and dereferencing it will lead to undefined behavior.

And unless you need to keep compatibility with C, then in C++ use only actual references instead of emulating through pointers:

void update(int& a,int& b) {
    ...
    a = sum;
    b = diff;
}

and call it like

int sum, diff;
update(sum, diff);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I know that's what I'm supposed to do. I'm trying to gain a better understanding of reference semantics by learning why the method in the question doesn't work. – LastStar007 Nov 13 '18 at 07:00
2

You are assigning addresses of local variables (sum, diff which go out of scope once the function exits) to a and b. It is undefined behaviour to access those addresses in main. You can assign their values instead.

*a = sum; 
*b = diff;
P.W
  • 26,289
  • 6
  • 39
  • 76
  • So since it's UB, whatever compiler HackerRank uses sets the variables back to their previous values? I didn't expect that. – LastStar007 Nov 13 '18 at 07:01
  • We cannot reliably predict what happens with undefined behavior. Anything is possible. "there are no restrictions on the behavior of the program" – P.W Nov 13 '18 at 07:03
  • True. I just didn't expect the compiler to hold onto the old values. – LastStar007 Nov 13 '18 at 07:11
  • @molbdnilo: using the addresses of local variables that have gone out of scope after a function exits and dereferencing them in main is not undefined behavior? – P.W Nov 13 '18 at 07:58