0

I'm trying to learn C++ and had a question about returning arrays in C++. I know that in this case perhaps Vector may be better and that there is no need for a getter method as the fields are visible within the same class but I'm trying to learn about memory management so I'll use them.

class Color {
    double r;
    double g;
    double b;
    public:
    Color(int a, int aa, int aaa) {
        r = a;
        g = aa;
        b = aaa;
    }

    bool operator==(const Color &other) {
        double *otherCol = other.getter();
        return otherCol[0] == r && otherCol[1] == g && otherCol[2] == b;
    }

    double* getter() const {
        double second[3] = {r,g,b};
        return second;
    }
};

int main() {
    Color col1(23, 54, 200);
    Color col2(23, 54, 200);
    cout << (col1 == col2) << endl;
    return 0;
}

This code should print out a 1 if the RGB colors are the same and 0 otherwise. But it does not print a 1. To debug, I added the following lines (twice on purpose) right before the return statement in operator==:

cout << otherCol[0] << " " << otherCol[1] << " " << otherCol[2] << endl;
cout << otherCol[0] << " " << otherCol[1] << " " << otherCol[2] << endl;

Oddly enough, the results are different:

23 54 200
6.91368e-310 6.91368e-310 3.11046e-317

Can someone please tell me what causes this and what would be a reasonable remedy that does not rely on Vector or dynamic allocation of memory? Let's assume that we don't want to pass in an array into getter() to update.

HikeTakerByRequest
  • 333
  • 1
  • 2
  • 15

1 Answers1

1

In getter you are returning the address of a local variable which results in undefined behavior so you are getting random memory. If you return a pointer you have to do something like new the variable in the called function and delete it after the function returns.

Or you could make second a class member which would keep it from going out of scope.

You could also pass the array in as a parameter.

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47
  • I thought I read somewhere that when a variable is returned from a function, a copy is made and returned so even when the function is out of scope, it works. Why is that not the case here? Is there a way to do this without dynamic memory alloc? – HikeTakerByRequest Aug 09 '15 at 21:47
  • @Manbearpig A copy is made, but here it is a copy of the address of the local variable which goes out of scope at the end of the function so the memory location is invalid when the function returns. – edtheprogrammerguy Aug 09 '15 at 21:48
  • So that only works for non-pointers? As in because the array is just a pointer to doubles, it does not work? – HikeTakerByRequest Aug 09 '15 at 21:49
  • It works for primitive types like `int` and also works if you return a first class object (not a pointer) which will call the copy constructor of the returned class. It never works with pointers to local variables. – edtheprogrammerguy Aug 09 '15 at 21:50
  • I see, that's one good thing to learn. My first intuition was to just dynamically allocate memory for `second[]` in `getter()` or to declare the array in the calling function but someone had told me, after looking at my code, that the array can be returned by value. Thus, I was seeking other avenues. I guess not then? – HikeTakerByRequest Aug 09 '15 at 21:53
  • 1
    @Manbearpig Your first intuition was correct :) – edtheprogrammerguy Aug 09 '15 at 21:54