Returning a reference to a local variable

Why this code can work successfully in the Code :: block. IDB just reports

warning: "link to local tmp variable returned",

but successfully print the result "hello world."

#include <iostream> #include<string> using namespace std; const string &getString(const string &s) { string tmp = s; return tmp; } int main() { string a; cout<<getString("hello world")<<endl; return 0; } 
+2
c ++ reference compiler-warnings local-variables
source share
8 answers

Perhaps this link will help you.

+1
source share

When you exit the function, all local variables are destroyed. By returning a link to tmp , you return a link to an object that soon ceases to exist (that is, technically, the address of a memory region whose contents no longer make sense).

Access to such a dangling link causes what is called "w90 behavior", and, unfortunately, "work as usual" is one of the undefined behaviors. What can happen here is that std::string stores a small static buffer for small strings (unlike large strings for which it grabs memory from the heap), and after getString exits, the stack space occupied by this string is not reset so it still works.

If you try to build debugging or call another function between them (which will effectively overwrite the stack space), it will no longer work.

+2
source share

You invoke undefined behavior. The standard does not indicate what happens in this case, however, your compiler has detected it.

+1
source share

tmp disappears the moment you return from getString . Using the returned link is undefined behavior, so anything can happen.

To fix your code, return the string by value:

 string getString(const string &s) { ... 
+1
source share

Are you sure? It needs segfault (it will be with gcc on most platforms). This code contains an error, and if you get “lucky” and it works, then you are cleaning the nasty error under the carpet.

Your string is returned by reference, that is, instead of creating a new string that is valid in the context in which you are returned, a pointer to an obsolete, destroyed object is returned, which is bad. const string getString... will execute as an declaration for the return type of the function.

0
source share

The temporary object is freed, however its contents are still on the stack until something is rewritten. Try calling several functions between the function call and the listing of the returned object:

 const string& garbage = getString("Hello World!"); callSomeFunctionThatUsesALotOfStackMemory(); cout<< garbage << endl; 
0
source share

The C ++ standard reports that binding a temporary object to a constant link extends the lifetime of the temporary resource of the link itself. Thus, the code should work on any standard compiler, but the practice itself is not very good in my view.

If you use your own string, which is not currently used in your example as the string a = getString ("Hello World!"), You just make a copy, and in the case of const string & a = getString ("Hello World!") bet that you should never have your temporary rubbish.

0
source share

As you can see, the example code below is slightly modified by calling goodByeString (). Like other answers, the already specified variables in getString, called tmp, are local. the variable leaves the scope immediately after the function returns. since it is installed on the stack, the memory remains valid when the function returns, but as soon as the stack grows again, this part of the memory where tmp is located overwrites with something else. Then the reference to a contains garbage.

However, if you decide to infer b because it is not returned by reference, the content remains valid.

 #include <iostream> #include<string> using namespace std; const string &getString(const string &s) { string tmp = s; return tmp; } string goodByeString(const string &s) { string tmp = "lala"; tmp += s; return tmp; } int main() { const string &a = getString("Hello World!\n"); string b = goodByeString("ciao\n"); cout << a << endl; return 0; } 
0
source share

All Articles