why return reference to local variable works?

closed account (N8hM4iN6)
Doesn't it release the addr when finish running a function, and why i return a reference to a int type back to the main works, and a reference to a string doesn't?

1
2
3
4
5
string& rr(void)
{
	string h = "hello world!";
	return h;
}


then it break.

but it works:
1
2
3
4
5
int& rr(void)
{
	int h = 100;
	return h;
}
In the first example, you are returning string, not string&. In the second, you are not returning the address of h, you are returning an int at memory address 0x100.
Daleth, wrong on both counts.

The appearance of working and actually working are entirely different things. What output do you get for the following code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

int& func1()
{
    int h = 100 ;
    return h ;
}

int& func2()
{
    int k = 1000 ;
    return k ;
}

void show( const int& intref, const char* str )
{
    std::cout << str << ": " << intref << '\n' ;
}

int main()
{
    int& r1 = func1() ;
    show(r1, "r1") ;

    int& r2 = func2() ;
    show(r2, "r2") ;
    show(r1, "r1") ;
}


The output when I ran it:
r1: 61143004
r2: 61143004
r1: 61143004
Oh, so the functions are able to return the memory addresses of the variable without the need to explicitly append the reference operator?
That happens because when pointer or reference invalidates, be it because of dynamic memory deallocation or popping value out of stack, it doesn't just vanish. Instead, memory which contained said variable marked as "free" and can be reused. But it might not be reused immideatly and variable still can be accessed for some time but nobody knows, when that memory will be overwritten.
Not working string probably caused by fact that string is not a simple type and destructor which called at the end of function can make some internal pointers point to 0 which will cause error if you will try to use method accessing those.
Oh, you mean a situation like this?
http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope

I didn't think of it that way, thanks!
There is no reference operator, and there is no notion of addresses here. What's returned are dangling references (references which refer to an invalid object.) We know references are returned, because the functions say they return references.
closed account (N8hM4iN6)
cire, the code you gave, it's not cout << &r1;, why it shows the addr finally? why cout reference display its addr, fainting...

and i code
1
2
3
int x = 10;
int& xx = x;
std::cout << xx;


it shows the value, what's differences? won't it because the function passing?
:0
closed account (N8hM4iN6)
MiiNiPaa, i think i understand what you said. it is tagged free when function terminates but not necessary be reused immediately, so i can access it some times, and some times not, Right?

thanks the link from Daleth, it illustrates the same thing :)

:\ now my problem is the code cire gave..
Last edited on
cire's code isnt showing you adresses. It shows garbage values which just happens to be in place where reference point to. It can be anything from second letter of str argument to half of return address of function and another half of return value of previous function. Actual value will change everytime you do something with your code. I had
r1: 0
r2: 0
r1: 0
when I turned off optimization,
r1: 1 
r2: 0 
r1: 1
when I used -O2,

r1: 2031646
r2: 0
r1: 2031646
When using -O3.
Last edited on
cire, the code you gave, it's not cout << &r1;, why it shows the addr finally? why cout reference display its addr, fainting...


It doesn't show the address. It shows the value. The value it shows may well be it's own address, since references are often implemented as pointers under-the-hood, and the referenced object may well occupy the same memory as the reference that was fed to show.

In other words, the memory that is being interpreted as an int via the reference is being reused, and when you access it via the reference you get a value that isn't what you would expect because of that reuse.

and i code

1
2
3
int x = 10;
int& xx = x;
std::cout << xx;



it shows the value, what's differences? won't it because the function passing?


The difference is that xx is an alias for a valid object. In mine (and your original code,) it is not. It may appear to work, but it isn't actually "working."
Last edited on
closed account (N8hM4iN6)
if i don't declare a reference in the main() to recieve the reference from other functions and directly use cout to display it, it shows the value..
 
std::cout << func1();

i wanna say, it's really complicated!

Anyway, i'll try my best to avoid returning a local variable.

thanks alot~ :)
Anyway, i'll try my best to avoid returning a local variable.


For completeness, if the local variable is static, everything will work fine.

1
2
3
4
5
6
int & reti()
{
    static int i;

    return i;
}



Edit: also the above lets you do funky stuff like:

1
2
3
reti() = 555;

std::clog << reti() << '\n';
Last edited on
@]Andy Zehn


An object of type std::string keeps its data in dynamically allocated memory, Only some auxiliary data are kept in the stack. So then the control exits the function the destructor of class std::string is called which deletes data in the heap.

string& rr(void)
{
string h = "hello world!";
return h;
}

std::string s = rr(); // the destructor was called.

In the second example variable h totally is allocated in the stack. So exiting the function does not result in destroying the stack. So until stack will be overwritten by some other data or some called function variable h will be present in the stack.

1
2
3
4
5
6
7
int& rr(void)
{
	int h = 100;
	return h;
} 

int i = rr(); // the stack was not destroyrd 


However such a behavior is undefined because in general case you can not guarantee that stack will not be rewritten by some other data, function, or thread.
Last edited on
Topic archived. No new replies allowed.