STL data structures using memory

W

wtnt

Hello,
I've been using the STL libraries for some time, but still don't know
the ins and outs of its implementation. Could this be because there's
more than 1 implementation?
Does anyone know of a good book out there or article that details how
one should handle memory usage when using the STL data structures,
like vector, map, etc.
Specifically, I mean things like when you put a key (char*) into a
map, does it copy this? Can I delete it right away? Can I only delete
it only after I've finished using my map? What about objects and not
just primitive types.
Same with vector, if I have a vector of myStruct. Do I need to go
through the vector and delete them or does the vector destructor do
that?
In general, I've been going with the rule of if they are pointers, I
am responsible, otherwise the vector class will handle it. But what
if I do:

vector<myObject> myVector;
myObject* obj = new myObject();
myVector.push_back(*obj);

Then what happens? Was this copied? Should I put delete obj here, or
at the end of the program, or never?

You see what I mean. A book that really explains the memory handling
would be very useful. thanks!
 
J

John Brown

vector said:
myObject* obj = new myObject();
myVector.push_back(*obj);

Then what happens? Was this copied? Should I put delete obj here, or
at the end of the program, or never?

You see what I mean. A book that really explains the memory handling
would be very useful. thanks!

Simply put, all collection classes store *copies* of whatever you store.
Each stored object must therefore be "copy constructible", i.e., your
user-defined types (classes and structs) must provide both a copy
constructor and copy assignment operator that each produce an *exact* copy
of the original (for all intents and purposes). You can rely on the
compiler-generated versions of these however (implicitly created if you
don't create your own), provided that they also produce an exact copy -
otherwise you must provide your own (the compiler-generated versions do a
member-wise copy of all members only which may not suffice if memory or
other resources must be internally copied - simply copying member pointers
to allocated memory for instance won't do since the memory itself doesn't
get copied, only the pointers themselves - so you need to write your own
copy constructor and copy assignment operator to duplicate this memory). The
bottom line is that you must free any resources that you yourself allocate.
Thus, you must delete "obj" in your example above because the call to
"push_back" merely stores a copy of this as discussed (by invoking its copy
constructor or copy assignment operator). The original must still be deleted
by you.
 
C

Cy Edmunds

wtnt said:
Hello,
I've been using the STL libraries for some time, but still don't know
the ins and outs of its implementation. Could this be because there's
more than 1 implementation?
Does anyone know of a good book out there or article that details how
one should handle memory usage when using the STL data structures,
like vector, map, etc.
Specifically, I mean things like when you put a key (char*) into a
map, does it copy this? Can I delete it right away? Can I only delete
it only after I've finished using my map? What about objects and not
just primitive types.
Same with vector, if I have a vector of myStruct. Do I need to go
through the vector and delete them or does the vector destructor do
that?
In general, I've been going with the rule of if they are pointers, I
am responsible, otherwise the vector class will handle it. But what
if I do:

vector<myObject> myVector;
myObject* obj = new myObject();
myVector.push_back(*obj);

This is a poor way to use std::vector. Much better:

vector<myObject> myVector;
myVector.push_back(myObject());

I wouldn't use operator new() unless the design were polymorphic. It's
slower and prone to memory management problems. If you must, do this:

typedef boost::shared_ptr<myObject> ObjectPtr;
vector<ObjectPtr> myVector;
myVector.push_back(ObjectPtr(new myObject()));

Unless myObject is a base class for a family of polymorphic classes this
approach doesn't make much sense.
Then what happens? Was this copied? Should I put delete obj here, or
at the end of the program, or never?

You see what I mean. A book that really explains the memory handling
would be very useful. thanks!

Standard containers don't do anything special with pointers. AFAIK they all
make shallow copies of whatever you put in them. I never use raw pointers in
standard library containers because I want the containers to manage the
memory for me.

The best book I know on the standard library is Josuttis ISBN 0-201-37926-0
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top