Reputation: 19
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.sstatic.net/v0Ref.png
Thanks for the help.
Edit: sorry, I had some problems with the image, apparently I need to work on my rep.
Upvotes: 0
Views: 90
Reputation: 5836
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.
Upvotes: 1
Reputation: 7637
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.
Upvotes: 1
Reputation: 8607
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.
Upvotes: 1