Reputation: 8207
I've got the following function:
MyFunction(const char *value, bool trigger) {
if (trigger) {
std::string temporaryString = getTemporaryStringFromSomewhereElse();
value = temporaryString.c_str();
}
// do processing here
// I need `value` and `temporaryString.c_str();` to be alive and accessible here and not destroyed
MyClass *object = new MyClass(value);
object->Work();
// etc..
}
So, the question is, how can I "prolong" the lifecycle of the temporaryString
outside of the scope of the if
-clause?
Currently, I'm getting the following error:
Using pointer to local variable 'temporary' that is out of scope.
I understand this is related to the memory management, and the fact that the temporary
is assumed to be "destroyed" or cleared from the memory after the if
-clause. But I need to either prolong its life cycle, or to create another string (copy) which will have a different, wider scope.
How can I achieve this?
Requirements:
MyFunction(const char *value, bool trigger)
value
later on to initialize another object, do some other work. I cannot have 2 variables, e.g. value
and anotherValueToBeUsedIfTriggerIsTrue
.Upvotes: 0
Views: 382
Reputation: 597205
Simply move the declaration of the std::string
out of the if
block, up into the function block, eg:
MyFunction(const char *value, bool trigger) {
std::string temporaryString;
if (trigger) {
temporaryString = getTemporaryStringFromSomewhereElse();
value = temporaryString.c_str();
}
// do processing here
MyClass *object = new MyClass(value);
object->Work();
// etc..
}
The std::string
will be blank initially, and destroyed when the function exits, and as such the reassigned value
will remain valid while the function is running, as long as temporaryString
is not modified.
Upvotes: 1
Reputation: 25623
I prefer std::optional
in that case as it also shows if the requested object was set or not.
Example:
std::string getTemporaryStringFromSomewhereElse()
{
return "Here I am";
}
std::optional< std::string > MyFunction(bool trigger) {
if (trigger) {
return getTemporaryStringFromSomewhereElse();
}
return std::nullopt;
}
int main()
{
auto retval = MyFunction( true );
if ( retval )
{
std::cout << *retval << std::endl;
}
}
EDIT: ( After we got the info that the interface is not changeable )
This ends up in the question of ownership!
Who will allocate the memory of the passed string and who is responsible to free that memory.
Options:
BTW: Keeping broken interfaces is a good start point for bad software :-) In the given case if also empty strings are valid, you start hacking with flags in arrays and all that broken stuff ( normally we should use structs with flags in it as already defined with std::optional ).
Upvotes: 1
Reputation: 408
static storage is probably what you are searching for.
static
attribute to a variable extends its life time to the whole program execution time.
void MyFunction(const char *value, bool trigger) {
if (trigger) {
static std::string s_buffer; // Note : this line is executed only once so don't assign the value here
s_buffer = getTemporaryStringFromSomewhereElse();
value = s_buffer.c_str();
}
// use of value is still correct even outside the if statement.
}
Note : in case of multi threading programs use of static isn't thread safe, for this porpose the standard provides thread_local storage.
Upvotes: 1