Why reference to a local variable is still valid [duplicate] - c++

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I am running following simple program in C++ program:
#include <iostream>
using namespace std;
string& ShowString()
{
string s1 = "abcd";
return s1;
}
int main()
{
string s2 = ShowString();
cout << s2 << endl;
return 0;
}
and the output is: abcd
The problem is that function ShowString returns a reference to a local variable and by the time that program reaches to cout << s2 << endl, s1 should have been destroyed (and also s2). But the output is still correct, which brings me to the conclusion that although s1 no longer exists, its contents in stack memory are still valid (probably until something else overwrites it).
I appreciate if you could let me know whether this conclusion is correct.
Thanks

Because it is an Undefined Behaviour. You can't trust that value.

Related

Why is it safer to force type conversion to a temporary object of a class than to wait for the argument to be automatically converted implicitly [duplicate]

This question already has answers here:
What is a dangling reference? [duplicate]
(1 answer)
Why is the phrase: "undefined behavior means the compiler can do anything it wants" true?
(2 answers)
When should I use std::thread::detach?
(6 answers)
Closed 5 months ago.
I have written a simple multi-threaded program as follows:
#include <iostream>
#include <thread>
using namespace std;
void myprint(const string& s)
{
cout << s << endl;
}
int main()
{
char buf[] = "hello world!";
thread obj(myprint, buf);
obj.detach();
cout << "end!!!" << endl;
}
This approach proved to be unsafe, as the main thread could end before the string was implicitly converted
A successful solution is to construct the string as a temporary string object when the passing of parameters, e.g thread obj(myprint, string(buf));
Perhaps it is because I have doubts about when threads begin to exist and I cannot understand why this solution is successful.Why artificially constructed temporary objects do not die out with the end of the main thread
The problem is that main() is returning before your thread has had a chance to fully execute. That means that the int m local variable declared inside main() gets destroyed, and then any subsequent reads of that variable (via the m_i reference in your TA object) by the thread invoke undefined behavior -- most likely that memory location got overwritten by some other data which (often) happens to be zero.
The fix is to replace myobj.detach() in your main() function with myobj.join(), so that main() will not return until after the child thread has exited, and therefore the m variable will remain valid across the child thread's entire lifetime.

When does a non-dynamic variable goes out of scope if being referenced by a pointer? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 2 years ago.
I'm new to C++ programming and I am having some hard time understanding some concepts.
Take this code as a example:
// Example program
#include <iostream>
class nber
{
int* value;
public:
nber(int n)
{
value = &n;
}
int getNber()
{
return *value;
}
};
int main()
{
nber var(111);
std::cout << "The number is:" << var.getNber() << "\n";
}
As you can see, the nber constructor receives an integer n and passes its address to the "value" pointer. What I expected is to have some kind of unwanted behavior, since the scope of the received integer (n) ends as soon as the constructor end, but the output is:
The number is:111
So the scope didn't end? If it really didn't end, when is the memory used to store the variable n going to be released? Thanks.
The scope did end. What you're seeing is Undefined Behavior - anything can happen. The number could be "purple", as far as the rules say. Or your hard disk could be erased. The latter is a bit rare, though.

C++ reference bug [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I tried to understand how c++ references work and I tried to write the next code:
#include <iostream>
int& func();
int main()
{
std::cout <<func()<< std::endl;
system("pause");
return 0;
}
int& func()
{
int x = 23;
return x;
}
for my understanding, the int x which was initialized in the function will be erased after the func ends and then the value that the function is returning will point to something that doesn`t exist.
But when I print it I get 23 in the console.
How does it possible?
The value is written in the memory inside func(), but you are wrong in "doesn't exist" after return.
Why would it not exist, did anything else overwrite that memory? You can't be sure. It's undefined behavior.
You are just returning a memory adress from func() which after return is made available for other variables. But if that (now available) memory adress is not overwriten, it will hold the value 23.. Until the end of days ;)
Here's #George 's reference to undefined behavior :
https://en.cppreference.com/w/cpp/language/ub
Furthermore your code might have some errors... Anyway, look at this and it shall solve your worries
Can a local variable's memory be accessed outside its scope?

string allocation in C++: why does this work? [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
void changeString(const char* &s){
std::string str(s);
str.replace(0, 5, "Howdy");
s = str.c_str();
}
int main() {
const char *s = "Hello, world!";
changeString(s);
std::cout << s << "\n";
return 0;
}
When I run this code, it prints "Howdy, world!" I would think that str gets destroyed when changeString exits. Am I missing something with the way std::string gets allocated?
Yes, str is destroyed; but the memory of the string isn't cleared; your "s" pointer point to a free but non cleared memory. Very dangerous.
It's undefined behaviour when std::cout << s tries to access the pointer, because the destructor of the local std::string in changeString has freed the memory which the pointer still points to.
Your compiler is not required to diagnose the error but can instead generate a binary which can then do whatever it wants to.
The fact that you got the desired output was just bad luck because it made you think that your code was correct. For instance, I've just compiled your code on my machine and got empty output instead. It could also have crashed, or it may have done other, unrelated things.

Returning a reference in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
Consider the following code where I am returning double& and a string&. It works fine in the case of a double but not in the case of a string. Why does the behavior differ?
In both cases the compiler does not even throw the Warning: returning address of local variable or temporary as I am returning a reference.
#include <iostream>
#include <string>
using namespace std;
double &getDouble(){
double h = 46.5;
double &refD = h;
return refD;
}
string &getString(){
string str = "Devil Jin";
string &refStr = str;
return refStr;
}
int main(){
double d = getDouble();
cout << "Double = " << d << endl;
string str = getString();
cout << "String = " << str.c_str() << endl;
return 0;
}
Output:
$ ./a.exe
Double = 46.5
String =
You should never return a reference to a local variable no matter what the compiler does or does not do. The compiler may be fooled easily. you should not base the correctness of your code on some warning which may not have fired.
The reason it didn't fire here is probably that you're not literally returning a reference to a local variable, you are returning a variable that is a reference to a local variable. The compiler probably doesn't detect this somewhat more complex situation. It only detects things like:
string &getString(){
string str = "Devil Jin";
return str;
}
The case of the double is simpler because it doesn't involve constructing and destructing a complex object so in this situation the flow control analysis of the compiler probably did a better job at detecting the mistake.
The reference to a double refers to a location that is still physically in memory but no longer on the stack. You're only getting away with it because the memory hasn't been overwritten yet. Whereas the double is a primitive, the string is an object and has a destructor that may be clearing the internal string to a zero length when it falls out of scope. The fact that you aren't getting garbage from your call to c_str() seems to support that.
GCC used to have an extension called Named Returns that let you accomplish the same thing, but allocated the space outside the function. Unfortunately it doesn't exist anymore; I'm not sure why they took it out
Classic case of a Dangling reference in respect to C++.The double variable was not on call stack while returning reference was trying to access it invoking the compiler to set the guarding flags. String however has explicit Garbage Collection mechanism which lets your compiler to overlook the scenario.