-7

I can't solve this problem.

Before use cout, I can see correct values.

But after use cout, why values are changed?

Is it caused by cout?

please tell me why...

#include <iostream>
using namespace std;     

/*    
03_CPP_Refer.ppt p27 excercise02    
*/

typedef struct Point {    
    int xpos;    
    int ypos;    
} Point;

Point& pntAddr(const Point &p1, const Point &p2) {
    Point rst;
    rst.xpos = p1.xpos + p2.xpos;
    rst.ypos = p1.ypos + p2.ypos;

    return rst;
}
/*
Point struct add
*/
void ex03_02() {
    Point * p1 = new Point;
    Point * p2 = new Point;

    p1->xpos = 3;
    p1->ypos = 30;
    p2->xpos = 70;
    p2->ypos = 7;

    Point &result = pntAddr(*p1, *p2);

    cout << "[" << result.xpos << ", " << result.ypos << "]" << endl;//correct result [73, 37]

    std::cout << "[" << p1->xpos << ", " << p1->ypos << "]+";
    std::cout << "[" << p2->xpos << ", " << p2->ypos << "]=";
    cout << "[" << result.xpos << ", " << result.ypos << "]" << endl;//incorrect result [ garbage, garbage ]


    delete p1;
    delete p2;
}

void main(int argc, char * argv[]) {
    ex03_02();
}

output :
[73, 37] : correct value
[3, 30]+[70, 7]=[13629668, 13630652]

IBJ
  • 7
  • 1
    You're returning a reference to a temporary in `pntAddr`. Don't do that. That invokes undefined behaviour. – Henri Menke Nov 05 '17 at 07:01
  • Before you used `cout` in contrast to what? – user0042 Nov 05 '17 at 07:02
  • 3
    Possible duplicate of [C++ Returning reference to local variable](https://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable) – HMD Nov 05 '17 at 07:08

4 Answers4

2

In function pntAddr You are returning reference to local variable. This will cause undefined behavior and of course undefined behavior sometime can be the expected result but you can't relay on that.

HMD
  • 2,202
  • 6
  • 24
  • 37
1

Your function shouldn't return a reference to a local variable, because when the function ends, it deallocates the local variable and returns a reference to it, causing undefined behaviour. What you can do is removing the reference, returning a copy instead.

Point pntAddr(const Point &p1, const Point &p2) {
Point rst;
rst.xpos = p1.xpos + p2.xpos;
rst.ypos = p1.ypos + p2.ypos;

return rst;
}

You can also pass a point by reference and set the values inside.

void pntAddr(const Point &p1, const Point &p2, Point& rst) {
rst.xpos = p1.xpos + p2.xpos;
rst.ypos = p1.ypos + p2.ypos;
}

Then you can just use it like this:

Point rst;
pntAddr(*p1, *p2, rst); // Now rst contains the result
Ricardo Antunes
  • 397
  • 2
  • 11
0
Point& pntAddr(const Point &p1, const Point &p2) {
Point rst;
rst.xpos = p1.xpos + p2.xpos;
rst.ypos = p1.ypos + p2.ypos;

return rst;
}

In the pntAddr function you are returning a local variable (variable declared inside the function) So what this does is that it destroys the local variable as soon as the function ends. So, now that there is no value to return it returns a garbage value.

That is why you were getting a garbage value.

Another problem is this

Point &result = pntAddr(*p1, *p2);

In code blocks this is giving a runtime error. I haven't figured it out why, so any help would be appreciated.

aditya rawat
  • 154
  • 10
  • It gives a runtime error because you trying to get a reference from a function that doesn't return a reference. – Ricardo Antunes Nov 05 '17 at 08:37
  • if the return type of a function is a reference then it should return the reference of the return variable. Or you are saying that i have to explicitly specify that the function i am returning is a reference to other variable – aditya rawat Nov 05 '17 at 11:04
-2

Instead Of:

Point &result = pntAddr(*p1, *p2);

Use:

Point result = pntAddr(*p1, *p2);

This is because from the function pntAddr you are getting back the result as an address and you need to store it in a pointer or map it directly to the variable.

Akshit Grover
  • 782
  • 1
  • 5
  • 10