简体   繁体   中英

Is returning a C++ std::string object safe from memory leaks?

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 ).

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.

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.

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.

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".

As you said a string returnString is 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM