views:

108

answers:

6
+2  Q: 

memory management

This is a memory management question about c++ code.

using namespace std;
#include <iostream>
#include <string.h>

int main()
{
 string a="first";
 string *b= new string;
 *b=a;
 a="second";
 cout << *b << ", " << a;
 delete b;
 return 0;
}

We can deallocate the blocks of memory that stored the string that b pointed to. I'm assuming this means that b no longer has any meaning once this is done. We can deallocate b to free some memory. Why can we not deallocate a? I know that we can only delete/free pointers, but the string a must take up some memory somewhere. Is there some way that we can free the memory that the string a takes up? If there are enough strings initialized in the same way that a is initialized, wouldn't it be possible that memory runs out?

A: 

The memory allocated for a will be automatically freed after the function returns.

karlphillip
+4  A: 

The string a is declared on the stack. You can't manually free it, but it will be automatically freed once it leaves scope (for example, when the enclosing function returns). If you need to be able to free that memory mid-function, then declare it dynamically (as you did for b) instead.

bta
+1 Your answer is more complete then mine.
karlphillip
Or you can enclose the string in a smaller scope... not that it will be worth in most cases.
David Rodríguez - dribeas
+2  A: 

Automatic objects (like your a) are destroyed when they go out scope. See example below:

int main()
  {

    {
    string a="first";
    string *b= new string;
    *b=a;
    a="second";
    cout << *b << ", " << a;
    delete b; //b gets freed
    } //a gets freed because it has gone out of scope   
 /* You can write more code here that does not need a */
 return 0;

}

doron
A: 

a here is automatically allocated on the "stack", and will be automatically destroyed/deallocated when it goes out of scope.

When you use dynamic memory with new/malloc, it gets allocated onto the "heap", which is just a bunch of memory available to the program. You have to manage this manually, and the program doesn't know when to get rid of it.

If you are truly worried about memory in this case, you should just use dynamic memory allocation.

Edit: This gives a more complete explanation than what I am trying to say: http://en.wikipedia.org/wiki/Malloc#Rationale

orangeoctopus
+3  A: 

The string consists of a small object containing a pointer to the storage for the string data, whose lifetime is managed by the object. There's usually no need to worry about the memory taken up by the object itself, but if the string is large then you might want to free the storage without destroying the object.

Calling clear(), or assigning from an emptry string, might not free the storage. The way to make sure that it is freed is to swap the string with a newly-constructed temporary; the temporary's destructor will free it.

string().swap(a); // replaces `a` with an empty string

You can also do this to any of the standard containers.

Mike Seymour
+2  A: 

This is rather awkward.

<string.h> is a C header. It doesn't define string. It looks like your version of <iostream> directly or indirectly includes <string>, or there would be an error.

Literal strings (those things that are delimited by paired quotation marks) may be pretty much anywhere, including a read-only memory segment. (They do take up memory, but you've got to have an awful lot of text to have a significant impact: something like War and Peace isn't going to take a full meg.) In this case, a std::string is being initialized with that value, and later on has another value assigned to it. The std::string handles the memory it uses.

There is, in C++, almost no reason to have a pointer to a std::string. The std::string doesn't take up much space without its contents, and it manages the memory for the contents itself. Are you confusing this with char *?

You new a std::string for b, and then you assign another address to b without deleteing the memory. That's a memory leak. What you newed for b is still allocated out there, but there's no way to delete it, so it will take up memory for the duration of the program.

Then, once you have assigned the address of a to b, you delete b;. This is a Bad Idea, and will likely mess up something important in a probably unpredictable way. Only delete memory you've acquired with new. (The important thing here for deleteing is not that b is a pointer and should be deleted, but that the memory it points to was not gotten through new.)

The memory management works something like this. A string literal is allocated somewhere. All you know is that you shouldn't try to change it or delete it by any means. Use the value and don't touch the rest. A std::string manages the memory for its own contents, and will take care of that in its destructor. A variable that's declared in a function or other block will be destroyed once it's out of scope (although whatever it might point to won't automatically be destroyed; only if it's a smart pointer or manages its own memory or whatever). If you new memory, don't throw away the pointer value until it's deleted. If you haven't newed memory, don't delete it.

David Thornley
+1 for a detailed explanation of the code.
rturrado
Hmm, actually there's no memory leak there: author had written `string *b= new string; *b=a;`Memory leak would occur if he'd written:`string *b= new string;b=`Agree with other your statements, though.
Haspemulator