14

I'm fairly novice with C++'s strings so the following pattern may be a little fugly. I'm reviewing some code I've written before beginning integration testing with a larger system. What I'd like to know is if it is safe, or if it would be prone to leaking memory?

string somefunc( void ) { string returnString; returnString.assign( "A string" ); return returnString; } void anotherfunc( void ) { string myString; myString.assign( somefunc() ); // ... return; } 

The understanding I have is that the value of returnString is assigned to a new object myString and then the returnString object is destroyed as part of resolving the call to somefunc. At some point in the future when myString goes out of scope, it too is destroyed.

I would have typically passed a pointer to myString into somefunc() and directly assigned to values to myString but I'm striving to be a little clearer in my code ( and relying on the side effect function style less ).

4
  • In the first function, you could probably just do "return string("A string");" and have the same result. Commented Aug 22, 2011 at 15:56
  • @luiscubal This is a simplified example to illustrate the problem. Commented Aug 22, 2011 at 16:00
  • 2
    @luiscubal even return "A string"; is fine since std::string are constructible with c strings. Commented Aug 22, 2011 at 16:01
  • @Ugo True, I forgot about that. Commented Aug 22, 2011 at 17:51

5 Answers 5

10

Yes, returning a string this way (by value) is safe,albeit I would prefer assigning it this way:

string myString = somefunc(); 

This is easier to read, and is also more efficient (saving the construction of an empty string, which would then be overwritten by the next call to assign).

std::string manages its own memory, and it has properly written copy constructor and assignment operator, so it is safe to use strings this way.

Sign up to request clarification or add additional context in comments.

Comments

7

Yes by doing

 return returnString 

You are invoking the string's copy constructor. Which performs a copy* of returnString into the temporary (aka rValue) that takes the place of "somefunc()" in the calling expression:

 myString.assign( somefunc() /*somefunc()'s return becomes temporary*/); 

This is in turn passed to assign and used by assign to perform a copy into myString.

So in your case, the copy constructor of string guarantees a deep copy and ensures no memory leaks.

* Note this may or may not be a true deep copy, the behavior of the copy constructor is implementation specific. Some string libraries implement copy-on-write which has some internal bookkeeping to prevent copying until actually needed.

1 Comment

Actually, whether a deep copy is performed or not is entirely up to the particular Standard Library implementation you are using. GCC is using COW, so the copy constructor simply implies incrementing a counter.
5

You're completely safe because you're returning the string by value, where the string will be "copied", and not by reference. If you were to return a std::string &, then you'd be doing it wrong, as you'd have a dangling reference. Some compilers, even, might perform return value optimization, which won't even really copy the string upon return. See this post for more information.

Comments

2

Yes, it's (at least normally) safe. One of the most basic contributions of almost any reasonable string class is the ability to act like a basic value for which normal assignment, returns, etc., "just work".

Comments

0

As you said a string returnStringis created inside somefunc and a copy is given back when the function returns. This is perfectly safe.

What you want is to give a reference to myString to somefunc (don't use pointer). It will be perfectly clear:

void somefunc( string& myString ) { myString.assign( "A string" ); } void anotherfunc( void ) { string myString; somefunc(myString); // ... return; } 

2 Comments

This bypasses the return value optimizations generally performed by the compilers, so it is not an improvement.
What you want is to... why do you say that? I see little advantage to your code over what he's doing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.