views:

103

answers:

4

I have a c++ class with a member that is a string, something like:

class Phone {
string name;

void foo()
  {
    name = string("new_name");
  }
}

Now, within the function "foo", I reassign the string to "new_name". My question is:

  • What happens to the old, empty string? Is it correctly "freed"? Does it still occupy memory?
  • Now I initialize the string in the constructor of Phone to string("old_name"). Is this the same case as with the empty string before? What happens here to the old string "old_name"?
+4  A: 

Yes, std::string manages memory for you. (That's one of the reasons for its existence!) How it does that is an implementation detail (for example, it may use copy-on-write, reference counting, or deep copy semantics) but for the most part, std::string will always correctly free the memory if it is not needed anymore.

Of course, this is assuming that there are no bugs in the implementation of the assignment operators or the destructor of std::string (which is true for all classes that implement a non-default assignment operator/destructor).

In silico
Thanks a lot... this means, when I understand it correctly, that you really only have to care about stuff created with "new" to avoid memory leaks? (besides mallocs, of course..)
Jan Rüegg
@Jan Rüegg: Sort of. But you can always design around such issues. Read up on RAII. See http://www2.research.att.com/~bs/bs_faq2.html#finally
dirkgently
@Jan - Properly designed classes (which may, for example, use RAII) will tremendously help you write code that does not leak memory. See http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
In silico
+1  A: 
  • Assuming the assignment operator is properly written, the destructor would be called.
  • Assuming the destructor is properly written, the memory used is freed.
James Curran
Alternatively, the assignment operator will not call the destructor, and reuse the old allocated memory for the new value. Either way, it's the assignment operator's responsibility.
Philip Potter
In most cases the assignment operator will NOT call the destructor. In some cases `operator=` is implemented by copy construction and swapping `*this` with the local, after which the local will be destroyed. Only in rare cases I have seen `operator=` implemented in terms of destructor and in-place construction... But in quite a few cases assignment operators are written without calling the destructor at all.
David Rodríguez - dribeas
+2  A: 

If it's std::string we're talking about then everything is correctly freed.

However, what exactly happens under the hood is up to the implementation. Several std::string implementations use some form of reference counting, so it's implementation dependent.

Also note, that your code does the same as:

name = "new_name";

... and even more explicitly:

name.assign( "new_name" );
Kornel Kisielewicz
+1  A: 

What happens to the old, empty string? Is it correctly "freed"? Does it still occupy memory?

It typically should not occupy much memory (as long as you've not initialized it). On assignment the string may reallocate to. What you're doing is this:

  • Creating a temporary string object which is freed once the assignment is over at the ;
  • Copy constructing a new string using this temporary and then setting it to the original name variable.

Any memory reallocation will correctly free the original memory. Note: The compiler may or may not optimize some steps depending on your settings.

Now I initialize the string in the constructor of Phone to string("old_name"). Is this the same case as with the empty string before? What happens here to the old string "old_name"?

Depends. If you're using initializer lists then no, it is not the same. There is no assignment; only the copy constructor gets called.

dirkgently