This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
Is there another efficient way to write code below not using static string variable? The reason is that, I use the code below to illustrate the crash happening in a bigger project that uses this static string variable. But if I remove the static keyword, the code will not crash, but the contents of string variable are nothing.
std::string conversation;
const char *GetFoo()
{
static std::string word;
word ="hello ";
word +="buddy.";
word +=" How are things?";
return word.c_str();
}
void CallGetFoo()
{
const char *pp = GetFoo();
conversation +=pp;
cout<<pp;
}
int _tmain(int argc, _TCHAR* argv[])
{
CallGetFoo();
return 0;
}
You're experiencing the classic issue of returning a pointer/reference to data that is local to a function. When you remove the static keyword, then the word variable is destructed at the end of the function. That means the c_str that it returns is going to be garbage and you'll end up with undefined behavior. The static keyword keeps the object around so that it will remain the same through multiple calls to the function. Like the comments say, you're better off returning a std::string.
Returning a std::string will copy the contents of the local variable to the caller's std::string. More than likely, the compiler will be able to optimize out the copy and do something called Return Value Optimization (RVO), but that is a separate topic.
Related
This question already has answers here:
C++ return array from function [duplicate]
(7 answers)
Closed 2 years ago.
I'm creating some code to "parse" an IP address. Basically, I am working with some legacy code that only accepts IP addresses in the form "AAA.BBB.CCC.DDD" and would like to write in something like "10.2.4.3" and have the code work without needing to type in 010.002.004.003. The IP address is held in a char pointer and the function I wrote to add the zeros to the code returns another char pointer. Would the following main function be okay to use (i.e. no memory leaks or other issues)?
char* parser(char* ip) {
char out[16]; //16 is the length of the final IP address with the dots and \0 char at the end
//find output char array
return out;
}
int main() {
char *a="10.2.4.3";
a=parser(a);
return 0;
}
While my understanding of memory leak issues in C++ are that they are due to allocating with new and then not deleting at the end or allocating with new and then reassigning them, I'm honestly not sure in this case. Since a is statically allocated, does assigning it to the char pointer created in the parser function cause any type of memory leak or other issue?
No, you don't need a delete if you don't do any new. But your program suffers from a different problem:
char* parser(char* ip) {
char out[16]; //16 is the length of the final IP address with the dots and \0 char at the end
//find output char array
return out
}
This returns a dangling pointer. It won't be safe to access the returned value as it gets reused as soon as the function returns.
One way around that is minimally different from what you have is:
void parser(const char* ip, char* out) {
// todo: write to out here;
}
int main()
{
const char *a="10.2.4.3";
char out[16];
parser(a, out);
return 0;
}
But this would still look a lot like old C written in a C++ compiler. There's better constructs available.
This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Closed 6 years ago.
If I understand correctly, variables that are not dynamically allocated are supposed to be deleted at the end of their scope.
However, I wanted to try it out with this code (which I think is not correct as I am supposed to use dynamic allocation) :
int* function()
{
int a = 3;
return &a;
}
int main(int argc, char const *argv[]) {
int* a(function());
std::cout << *a << std::endl; // prints 3
}
Why can I still access the value of the variable a by using the pointer returned by the function when it is supposed not to exist anymore ?
a and hence the return value from function has gone out of scope. You are just lucky.
Just be careful and compile with all the warnings enables - and take heed of those warnings.
The fact that you can access the value is pure luck. The code has undefined behaviour (since the variable is destroyed) and the compiler can generate whatever it wants - but you cannot rely on it.
This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 8 years ago.
I guess its a storage/definition difference but still I cant find a straight explanation of the behaviour. I have a function that returns a locally defined char* in two ways:
//Try 1:
char* printSomething()
{
char arr[100];
sprintf(arr, "The data %u", 100);
return arr;
}
//Try 2:
char* printSomething()
{
return "The data 100";
}
When I print the result of the first function It displays nothing (C) or garbage (C++) while on the second it prints the correct data.
I know I should store the data on the heap in cases like this or define static variable but still, how come the first doesnt work while the second does? and also, can I count on the second way to always work?
The first is just undefined behavior because arr is released when the function ends, so you're left with a dangling pointer.
The second works because "The data 100" is a string literal with static storage duration, which means it persists throught the lifetime of the program.
The implicit conversion to char* is deprecated though, and changing the contents will result in undefined behavior. I suggest you return const char* or std::string.
In both cases you returning char*
The first you return a pointer to a local array variable, located on the stack, which no longer exists after you exit the function. and may be rewritten.
In the second you returning pointer to a const string, located on the code segment, and it exist as long as the program is running.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pointer to local variable
#include <iostream>
using namespace std;
char* func();
int main() {
char* str;
str = func();
cout<<str;
return 0;
}
char* func() {
char * str;
char p[] = "priyanka is a good girl";
str = p;
cout<<str<<"\n";
return str;
}
gives the output,
priyanka is a good girl
priy
I did not understand what just happened here, why an incomplete array was given as output. I am a little new with this. Please help.
Your function func() returns a pointer to a local variable, which later causes undefined behaviour when you try to access it.
In func2() char p[] is a local variable initialized on stack. Returning a pointer to stack variable is a bad idea(and is undefined behaviour as well), and I think your string "priyanka is a good girl" got overwritten when the function returned.
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.