Archived

This topic is now archived and is closed to further replies.

When to delete STL containers like list vector etc..

This topic is 4932 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I am wondering whether I need to delete STL containers or theyre destroyed automatically. If not then when should I destroy them? Say I have STL list.
// 1.

std::list<int> ID_Numbers;
ID_Numbers.push_back(89);
// etc... Do I need to delete this list on exit?



// 2. 

std::list<BoundingBox> Boxes;
BoundingBox box1;
Boxes.push_back(box1);
// etc... Do I need to delete this list on exit?


// 3. 

std::list<BoundingBox*> Boxes;
BoundingBox *box1 = new BoundingBox();   // Dynamic allocation

Boxes.push_back(box1);  
// etc... Do I need to delete this list on exit?


// 4. 

std::list<IteratorList> ItrListBoxes;
BoundingBox box1;
std::list<BoundingBox>::iterator itr = list.find(Box);
ItrListBoxes.push_back(itr);  
// etc... Do I need to delete this list on exit?

[edited by - papa on May 29, 2004 11:28:28 AM]

Share this post


Link to post
Share on other sites
1 and 2: No deletion necessary, the list and its contents will be destroyed when the list goes out of scope.

3: You need to go through the list(before it goes out of scope) and call delete on every pointer. The list itself will be destroyed when it goes out of scope.

--
AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.
[Project site] [Blog] [RSS] [Browse the source] [IRC channel]

Share this post


Link to post
Share on other sites
3) You have to delete the elements of the list, but not the list itself (assuming that you do not call delete on the Box1 variable)


std::list<BoundingBox*>::iterator iter = mylist.begin(), end = mylist.end();

for(;iter != end; ++iter)
delete *iter;



Only delete what you new, and only delete what you new once.

4) list does not have a find member.

Share this post


Link to post
Share on other sites
ok. IC. So to summarize list is destroyed when it goes out of scope and if it contains dynamically allocated structure then the structure must be destroyed before the list is destroyed.
What if the STL list contains a list of iterators (See case 4) or other pointers to some other structure. eg. I have an array of ints
int array[256];

then for eg. I want to store pointers to teh array in STL list structure:

eg.

list<int*> links;
links.push_back(&array[4]);
links.push_back(&array[100]);

Do I need to delete this list. I guess not. Am I right? As I am not using new anywhere. They are simply just pointers to array structure.
So there is no need to call STL clear() or erase() in destructor? I guess non of these functions will delete dynamically allocated memory stored in list either. It must be deleted manually as you mentioned right?



[edited by - papa on May 29, 2004 11:43:05 AM]

Share this post


Link to post
Share on other sites
Sorry Guys just last question if I could.

std::vector<char*>Names

Names.push_back("name1");
Names.push_back("name2");
Names.push_back("name3");

Will I have to delete each string (char*) manually or it will be destroyed automatically once 'Names' vector will go out of scope of function or on program exit? I know no new so dont delete but just to make sure in this case. Please let me know! thanks!

[edited by - papa on May 29, 2004 3:15:50 PM]

Share this post


Link to post
Share on other sites
Hopefully, this should make it clear. All of these are correct:
{
list foo;
for (int i = 0; i < 10; i++ )
{
int x = i;
foo.push_back( x );
}
...
}

{
list foo;
for (int i = 0; i < 10; i++ )
{
int * px = new int( i );
foo.push_back( px );
}
...
for ( list::iterator it = foo.begin(); it != foo.end(); ++it )
{
int * px = *it;
delete px;
}
}

{
list * pfoo = new list;
for (int i = 0; i < 10; i++ )
{
int x = i;
pfoo->push_back( x );
}
...
delete pfoo;
}

{
list * pfoo = new list;
for (int i = 0; i < 10; i++ )
{
int * px = new int( i );
pfoo->push_back( px );
}
...
for ( list::iterator it = pfoo->begin(); it != pfoo->end(); ++it )
{
int * px = *it;
delete px;
}
delete pfoo;
}
1. New and delete are paired.
2. STL containers are well-designed in that they clean up their mess but they don''t clean up your mess.

Share this post


Link to post
Share on other sites
thank you JohnBolton.

Sorry you must be fed up with me but I dont really know if you declare say:

char *name = "Name";

whether it should be deleted as it appears to me that its a pointer and as far as I now pointers should be deleted. I know there is no 'new' so I guess I should not delete it but thats why I asked about that particular example I posted above.

std::vectorNames
Names.push_back("name1");
Names.push_back("name2");

I thought I should delete it manually as it appreas to me that I am loading pointers. Sorry I am still learning about pointers thats why I am sooo confused.
So whenever I use pointers eg. storing pointers in some array then I dont have to delete those pointers? right? I know that if I create objects using new then those must be obviously deleted. But I was confused about pointers. I thought that pointers must be deleted if they are stored in some data structure. So they are automatically destroyed right?

say:
char *str = "string";
char **pstr = &str;

here the vaaribale str will be destroyed on exit and the pointer pstr too. yes? This is where I was confused.
Forgive me please



[edited by - papa on May 29, 2004 4:46:32 PM]

Share this post


Link to post
Share on other sites
This has been stated four times already, so I doubt repeating it a fifth time will have any effect. But just in case:

If you use new to create something, you must use delete to destroy it. If you do not use new to create something, then you do not use delete to destroy it.

There are no exceptions to this rule (at least none that you should be concerned with at this point).

new and delete are methods for creating and destroying objects. There are other methods and it is usually important and/or required that an object created using one particular method is destroyed using that same method.

In you last example, you don't use new, so you should not use delete.

Now pointers...

Pointers are used for lots of things, not just for new and delete. A pointer is simply a "handle" or a reference to an object. Its value also happens to be the location of the object in memory and that enables you to use a pointer for other operations more complicated than just referencing an object.


John Bolton
Page 44 Studios
Current project: NHL Faceoff 2005 PS2


[edited by - JohnBolton on May 29, 2004 5:13:34 PM]

Share this post


Link to post
Share on other sites
Hey papa,

When you type:

int Blah = 7; 


Blah is created on the stack, not on the heap. The memory for the integer Blah is allocated and deallocated for you by C++ according to the function's scope. Now when you say:

int* pBlah = &Blah; 


Just because pBlah happens to be a pointer doesn't mean that the memory it points at has to be deleted by you. In this example, the memory pointed at by pBlah is being controlled by C++ and the function's scope, so it would be illegal for you to try to delete memory that you're not supposed to manage.

Now take this example of "what not to do":

int* pBlah;

void SetValue()
{
int Blah = 7; // memory for Blah allocated
pBlah = &Blah;
} // memory for Blah implicitly deallocated

void PrintValue()
{
cout << *pBlah;
}


If you call the SetValue and then the PrintValue function, you are not guaranteed to get "7". This is because the memory that pBlah had pointed at has been deallocated by the SetValue function going out of scope.

Similarly, when you type,

char* pString = "Test"; 


you are creating a pointer to memory that is on the stack. pString does not need to be freed by you, and the memory pointed at by pString will be deallocated when the function goes out of scope.

I hope this helps...

[edited by - EvilSteve on May 29, 2004 7:53:01 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Incidentally, the memory for string literals (IE, char* blah = "Hello World" is not always on the stack. It''s wherever the compiler decides to stick it. Sometimes in the exe''s bytecode, sometimes with the static variables, but usually in some sort of string table.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I always believed

char *a = "here";

would point to code segment

Share this post


Link to post
Share on other sites