Topic: Help! Missing critical info on maps...


Author: olsonr@panix.com (Ron Olson)
Date: 1998/10/22
Raw View
Hey-

I've written a program that uses maps. Works great with one cavaet:
It never releases the memory of the objects in the map.

I am inserting a string key to an object I create dynamically. This works
great until I am near the end of the app and am extracting the data
from the map for a database update. Once this is done, I no longer need
the data (this is in a DLL so it's imperative I release the memory
manually as the app won't do it). Initially, I tried:

   delete (*theIterator).second;
 (*theIterator).second = NULL;

and later:

 theMap.erase(theMap.begin(), theMap.end());

but this only clears the map, not the memory of the objects in the map.

I've been experimenting with remove(), but with little success:

 theTempIterator = remove(theMap.begin(), theMap.end(), myTempObj);

where myTempObj is the same class type as (*theIterator).second and
was assigned "myTempObj = (*theIterator).second;"

Any ideas on what I may be doing wrong?

Thanks for any info,

Ron



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1998/10/23
Raw View
Have you tried allocating the map object on the heap and deleting it when
you no longer need what it contains. Some container implementations let the
containers grow as objects are added, but they never shrink until the
container itself is destroyed--or so I have been told.


Ron Olson wrote in message <70o5jb$a5t@panix3.panix.com>...


>I've written a program that uses maps. Works great with one cavaet:
>It never releases the memory of the objects in the map.

>I am inserting a string key to an object I create dynamically. This works
>great until I am near the end of the app and am extracting the data
>from the map for a database update. Once this is done, I no longer need
>the data (this is in a DLL so it's imperative I release the memory
>manually as the app won't do it). Initially, I tried:

>  delete (*theIterator).second;
> (*theIterator).second = NULL;

>and later:

> theMap.erase(theMap.begin(), theMap.end());

>but this only clears the map, not the memory of the objects in the map.

>I've been experimenting with remove(), but with little success:

> theTempIterator = remove(theMap.begin(), theMap.end(), myTempObj);

>where myTempObj is the same class type as (*theIterator).second and
>was assigned "myTempObj = (*theIterator).second;"

>Any ideas on what I may be doing wrong?

[ moderator's note: excessive quoting deleted. -sdc ]




[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/10/23
Raw View
Ron Olson wrote:
>
> Hey-
>
> I've written a program that uses maps. Works great with one cavaet:
> It never releases the memory of the objects in the map.
>
> I am inserting a string key to an object I create dynamically. This works
> great until I am near the end of the app and am extracting the data
> from the map for a database update. Once this is done, I no longer need
> the data (this is in a DLL so it's imperative I release the memory
> manually as the app won't do it). Initially, I tried:
>
>         delete (*theIterator).second;
>         (*theIterator).second = NULL;

This deletes the objects, but not the map entries

>
> and later:
>
>         theMap.erase(theMap.begin(), theMap.end());
>
> but this only clears the map, not the memory of the objects in the map.

This deletes the map entries (including the pointers), but not the
objects the map entries points to.
If you combine both, you should get the desired effect:

template<class Map> void clean_map_with_pointers(Map& map)
{
  for(Map::iterator i=map.begin(); i!=map.end(); ++i)
    delete (*i).second;
  map.erase(map.begin(), map.end()); // or simply: map.clear();
}

(I didn't set the pointers to NULL since they are removed
immediatly anyway).

Note that if you destroy the map itself, erase is not needed;
just do the deletes.

[...]

> Any ideas on what I may be doing wrong?

The point is that you don't have the obbjects in your map;
instead the map manages pointers to objects. For most operations
this is no important difference (you just have to use a different
access syntax), but on deleting, this difference is important.
Since the map doesn't know anything about the pointers it manages,
it won't do anything with the objects it points to.
Note that there's no way for the map to even know that your
pointers point to dynamically allocated objects, that you don't
need them later (you might have used the map just as an index
to existing objects), etc. The map is a simple container for
what you put in it, and it doesn't care that in this case you
have pointers - it just treats them like any other object,
and destroying a pointer doesn't delete what it points to.

If you don't like to have to delete your objects manually, you
should create some reference counted pointers and use those in
the map. Then the RC-pointers delete your objects on destruction.
Note that you cannot put auto_ptrs into the map (or any other
container) - it might be tempting; however the standard doesn't
guarantee anything in this case. The problem is that a temporary
copy would "steal" your object, and delete it on destruction.
(However, with old auto_ptr, it used to be even more dangerous,
since you couldn't even test if your object was stolen. Now
at least the affected pointer will reflect that theft by being
NULL.)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/10/23
Raw View
Ron Olson wrote:
>
> I've written a program that uses maps. Works great with one cavaet:
> It never releases the memory of the objects in the map.
>
> I am inserting a string key to an object I create dynamically. This
> works
> great until I am near the end of the app and am extracting the data
> from the map for a database update. Once this is done, I no longer
> need the data (this is in a DLL so it's imperative I release the
> memory manually as the app won't do it).

A map deletes the memory containing its elements. However, from your
example, I deduce that you've got a map that doesn't contain your
"objects" per se, but pointers to them. In this case, all that's freed
is the memory containing the pointers (plus the internal structures used
by the map). If you want the things pointed to by your map elements to
go away, you have to do that "manually."

> Initially, I tried:
>
>         delete (*theIterator).second;
>         (*theIterator).second = NULL;

That looks correct to me. Doesn't it work?

> and later:
>
>         theMap.erase(theMap.begin(), theMap.end());
>
> but this only clears the map, not the memory of the objects in the
> map.

Correct. But again, it's important to be clear about the meaning of
"object". In the context of STL, "object" doesn't necessarily mean
"structure of class type". A pointer is an object. Your map contains
"objects" which are pointers to other objects. Those other objects
aren't strictly speaking "in" the map.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/10/23
Raw View

Ron Olson wrote in message <70o5jb$a5t@panix3.panix.com>...
>
>Hey-
>
>I've written a program that uses maps. Works great with one cavaet:
>It never releases the memory of the objects in the map.


map will delete the memory it allocates.  You have to delete the memory you
allocate.  If your map's key or data is a pointer the map does not take
ownership of the pointed-at data.  The map will destroy elements that are
erased.  Destroying a pointer does not imply a call to delete.  If pointer
destruction doesn't have the semantics you need, store a class (perhaps a
smart pointer) that does do the right thing.

Good luck.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]