0

Alright, so I have looked around online and clearly my problem is that I'm using a variable "val" here that stops existing when the function closes. Unfortunately, I haven't really found any actual solutions to my problem here. I'm sure this is an easy enough problem to solve once you know how, but I just don't have the knowledge.

In this code, just notice I'm trying to return an unsigned int val. I can't do that because the code wants a reference, not just a variable. I can't simply return val but I don't know what to do.

https://i.stack.imgur.com/v0Ref.png

Thanks for the help.

Edit: sorry, I had some problems with the image, apparently I need to work on my rep.

TheDebaser
  • 19
  • 1
  • And why is this a problem? What are you actually trying to do? – juanchopanza Oct 13 '13 at 07:50
  • Then stop using `val` after the function closes. If you want some better advice you are going to have to post some of your code. – john Oct 13 '13 at 07:51
  • There's just no context here, you write as though there has been a previous conversation. Each question needs to be self-contained. – djna Oct 13 '13 at 07:52
  • I've looked at the code, it makes so little sense that I really can't offer an answer. However if you change this `const unsigned int & list::operator[]` to this `const unsigned int list::operator[]` then you will at least get rid of the problem in your question. But this code is still going to be wrong I'm afraid, it just doesn't make any sense at all. – john Oct 13 '13 at 07:56
  • 2
    You realize you could of just posted the code as text in a code block instead of an image of it... – Preet Kukreti Oct 13 '13 at 08:00

3 Answers3

1

I'm going to take a wild guess.

Foo& doStuff()
{
    // blah blah
    Foo val;
    // ...
    return val;
    // val is no longer valid end of scope. Returning invalid reference.
}

Either pass in the result Foo instance to doStuff, or create a new Foo on the heap and return as pointer.

So,

void doStuff(Foo& val)
{
    // blah blah
    // ...
    val = x;
}

or

Foo* doStuff()
{
    // blah blah
    Foo* val = new Foo;  // dont forget to delete
    // ...
    return val;
}

Of course, you can return by value:

Foo doStuff()
{
    // blah blah
    Foo val;
    // ...
    return val;
}

Depending on how heavy a Foo is. Of course, since in this case a Foo is just an small int, you should simply return by value. For some cases of return by value for large/non-trivial types, a temporary copy is created (In those instances where there is no copy elision via RVO or NRVO); in these cases you might want to avoid returning large object types by value.

Preet Kukreti
  • 8,417
  • 28
  • 36
1

This code has a lot of problems, apart from being given in an image (!!!)

I guess you're trying to find the element at position pos-1 in a list, or something. The main problem referring to your question seems to be that you're first assigning val by value, then you have no reference to return. You should return n2->value directly, which should be a reference to unsigned int, like that:

const unsigned int &list::operator[](unsigned int pos) const
{
    node *n1 = ???, *n2 = ???;

    for (unsigned int k = 0; k < _size; k++)
    {
        if (k == pos)
            return n2->value;

        n1 = n2->next;
        n2 = n1;
    }

    return ???;
}

Other problems remain, e.g.

  • why you need two node* and not just one (looking for position pos-1 directly)

  • how to initialize n1, n2 (somehow pointing to the head of your list; obviously new node() should not work)

  • what to return if input argument pos is out of range (possibly return a reference to some static variable that you can detect, or throw an exception)

For these problems, more context would be needed from your side.

iavr
  • 7,547
  • 1
  • 18
  • 53
  • Thanks for the response, my code works fine, I have a version of it that returns variables instead of a reference that passes a bunch of tests (although your third point is valid, I've since changed that. All I want to know is how can I get the const unsigned int stored in "n2->value" returned by the function. Should I make a global variable and return it? Should I make a global variable and return a pointer to it? How do I return the value stored in n2->value by reference? – TheDebaser Oct 15 '13 at 02:45
  • Maybe I am missing something, otherwise all you need is in my answer. If `n2->value` is of type `unsigned int` and lives longer than the call to `operator[]`, then `return n2->value` returns that value by (const lvalue) reference, since the return type is `const unsigned int &` (note the `&` at the end). – iavr Oct 15 '13 at 14:08
1

Reference variables, are only valid if the object to which "refer" to, exists in memory. Passing around references to an out of scope variable, is considered undefined behavior. This is the mistake in your code.Please correct it.

const unsigned int& list::operator[] (unsigned int pos)const
{
const unsigned int val = 0;

return val; //this is a local variable, whose scope ends here, a reference to this should not be returned
}

This is the compiler's warning, to your code.

warning: reference to local variable ‘val’ returned [enabled by default]

Please listen to compiler warnings (especially c/c++ !!), in your case simply using pass by value, would have been sufficient.

Edit:

In case the return variable, is enforced to be a reference type, and cannot be avoided, you can then extend the life of you local variable, to throughout the existence of the program by making it static.

const unsigned int& list::operator[] (unsigned int pos)const
{
static const unsigned int val = 0;

return val; 
}

Th variable val is now a static local variable, whose life is throughout the program, so pasing around references to this variable should be OK, but not recommended programming, since a pass by value will suffice for the needs of your application.

Barath Ravikumar
  • 5,658
  • 3
  • 23
  • 39
  • I think the problem is not how to return `val`, but the definition of `val` itself. What should be returned is `n2->value` directly, which should be a reference to some element of the list (see my answer). – iavr Oct 13 '13 at 09:09
  • I have not seen into the logic of the program, this is correction of the asker's basic concepts in c++.....The asker thinks, he can pass reference to any local variable,,,this is wrong... Concepts first, everything else comes later :) – Barath Ravikumar Oct 13 '13 at 09:11
  • The question specifically stated that "the code wants a reference, not just a variable". If so, returning by value is correct C++ but not an option here. – iavr Oct 13 '13 at 09:16
  • Nobody is stopping the asker to return a reference variable...It is just WRONG to return a reference to a local variable, instead he should use the RIGHT way, of allocating memory for "val" on heap, and then returning the reference to it....I suggest you read this http://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable ...Brilliant Answer..!! – Barath Ravikumar Oct 13 '13 at 09:22
  • Sorry, but to me all this still looks very nice but irrelevant :-) – iavr Oct 13 '13 at 09:30
  • Yes, that is my problem, now how do I solve it? Should I be throwing a reference to a global variable, is that it? – TheDebaser Oct 15 '13 at 02:34
  • Beagle Bone: I know I'm wrong, that's why I'm asking. There is also a very specific restriction that says I need to pass this by reference. I have one version of this code built the exact same way that passes by value and works fine. How do I return a value through reference? Why is there no straightforward answer to this, it must be possible. – TheDebaser Oct 15 '13 at 02:49