map.erase, key cleanup

  • Thread starter =?iso-8859-1?B?UultaQ==?=
  • Start date
?

=?iso-8859-1?B?UultaQ==?=

Can someone tell me whether or not my assumptions are good? Just want
to know if I'm going to run into trouble in how I'm deleting map
entries. Although I like to think I know my way around C++, I'm not an
STL expert by any stretch.

Here's a bit of code; notes on my assumptions follow:


_lookupMap is defined as:

map<string, long> _lookupMap;

I'm adding to it something like this:

string * newKey = new string("Some Key Value");
_lookupMap[*newKey] = someIntegerValue;

....and I'm deleting an entry like this (no error checking, assume
find() does actually find...):

string origKey = "Some Key Value";
map<std::string, Int32>::iterator oldEntry = _lookupMap.find(origKey);
const string oldKey = oldEntry->first;
_lookupMap.erase( origKey );


I'm wondering... Will the map object cleanup the string key, or do I
need to delete it myself? Given that the string object is created on
the heap but dereferenced when used as a key, I would assume that the
call to erase will cleanup the string object itself, and I just need to
make sure there aren't any other pointers to the object left lying
around.

Do I have this right?

Remi.
 
N

Nate Barney

Rémi said:
Can someone tell me whether or not my assumptions are good? Just want
to know if I'm going to run into trouble in how I'm deleting map
entries. Although I like to think I know my way around C++, I'm not an
STL expert by any stretch.

Here's a bit of code; notes on my assumptions follow:

_lookupMap is defined as:

map<string, long> _lookupMap;

I'm adding to it something like this:

string * newKey = new string("Some Key Value");
_lookupMap[*newKey] = someIntegerValue;

Unless you do:

delete newKey;

at some point before newKey goes out of scope, you have a memory leak.
A better way to do what it looks like you want to do is:

_lookupMap["Some Key Value"] = someIntegerValue;
...and I'm deleting an entry like this (no error checking, assume
find() does actually find...):

string origKey = "Some Key Value";
map<std::string, Int32>::iterator oldEntry = _lookupMap.find(origKey);
const string oldKey = oldEntry->first;
_lookupMap.erase( origKey );


I'm wondering... Will the map object cleanup the string key, or do I
need to delete it myself? Given that the string object is created on
the heap but dereferenced when used as a key, I would assume that the
call to erase will cleanup the string object itself, and I just need to
make sure there aren't any other pointers to the object left lying
around.

STL containers, including std::map, have copy semantics. What this
means is that values inserted into the containers are copied. So, your
code above allocates a new std::string, copies that std::string into the
map as a key, and then leaks the original std::string. The copied
std::string will be properly deallocated by the std::map, but it has no
relationship to the original string being passed in, other than having
an equal value.

Also, you should avoid using leading underscores in your identifiers,
because those are reserved for the compiler/standard library.

Hope this helps,
Nate
 
?

=?iso-8859-1?B?UultaQ==?=

An enormous help, actually.
Thanks a lot, Nate.

Remi.

Nate said:
Rémi said:
Can someone tell me whether or not my assumptions are good? Just want
to know if I'm going to run into trouble in how I'm deleting map
entries. Although I like to think I know my way around C++, I'm not an
STL expert by any stretch.

Here's a bit of code; notes on my assumptions follow:

_lookupMap is defined as:

map<string, long> _lookupMap;

I'm adding to it something like this:

string * newKey = new string("Some Key Value");
_lookupMap[*newKey] = someIntegerValue;

Unless you do:

delete newKey;

at some point before newKey goes out of scope, you have a memory leak.
A better way to do what it looks like you want to do is:

_lookupMap["Some Key Value"] = someIntegerValue;
...and I'm deleting an entry like this (no error checking, assume
find() does actually find...):

string origKey = "Some Key Value";
map<std::string, Int32>::iterator oldEntry = _lookupMap.find(origKey);
const string oldKey = oldEntry->first;
_lookupMap.erase( origKey );


I'm wondering... Will the map object cleanup the string key, or do I
need to delete it myself? Given that the string object is created on
the heap but dereferenced when used as a key, I would assume that the
call to erase will cleanup the string object itself, and I just need to
make sure there aren't any other pointers to the object left lying
around.

STL containers, including std::map, have copy semantics. What this
means is that values inserted into the containers are copied. So, your
code above allocates a new std::string, copies that std::string into the
map as a key, and then leaks the original std::string. The copied
std::string will be properly deallocated by the std::map, but it has no
relationship to the original string being passed in, other than having
an equal value.

Also, you should avoid using leading underscores in your identifiers,
because those are reserved for the compiler/standard library.

Hope this helps,
Nate
 
?

=?iso-8859-1?B?UultaQ==?=

STL containers, including std::map, have copy semantics. What this
means is that values inserted into the containers are copied. So, your
code above allocates a new std::string, copies that std::string into the
map as a key, and then leaks the original std::string. The copied
std::string will be properly deallocated by the std::map, but it has no
relationship to the original string being passed in, other than having
an equal value.

I know using pointers as keys isn't recommended, but would this imply
that if one were to use a pointer to an object as key type, you *would*
have to cleanup your key object as well?
From what you've just said, I'd assume that the pointer address would
be copied upon insertion into the container, and that the pointer would
eventually get cleaned up, but the object at that location in memory
would leak?

Remi.
 
N

Nate Barney

Rémi said:
I know using pointers as keys isn't recommended, but would this imply
that if one were to use a pointer to an object as key type, you *would*
have to cleanup your key object as well?
Correct.

From what you've just said, I'd assume that the pointer address would
be copied upon insertion into the container, and that the pointer would
eventually get cleaned up, but the object at that location in memory
would leak?

Again, correct, unless you call delete on the pointer first.

Nate
 
D

Daniel T.

Rémi said:
Can someone tell me whether or not my assumptions are good? Just want
to know if I'm going to run into trouble in how I'm deleting map
entries. Although I like to think I know my way around C++, I'm not an
STL expert by any stretch.

Here's a bit of code; notes on my assumptions follow:


_lookupMap is defined as:

map<string, long> _lookupMap;

I'm adding to it something like this:

string * newKey = new string("Some Key Value");
_lookupMap[*newKey] = someIntegerValue;

delete newKey;

You have to delete everything you new.
...and I'm deleting an entry like this (no error checking, assume
find() does actually find...):

string origKey = "Some Key Value";
map<std::string, Int32>::iterator oldEntry = _lookupMap.find(origKey);
const string oldKey = oldEntry->first;
_lookupMap.erase( origKey );


I'm wondering... Will the map object cleanup the string key, or do I
need to delete it myself? Given that the string object is created on
the heap but dereferenced when used as a key, I would assume that the
call to erase will cleanup the string object itself, and I just need to
make sure there aren't any other pointers to the object left lying
around.

Do I have this right?

You are working way too hard.

To add something to your lookupMap just do:

_lookupMap["Some Key Value"] = someIntegerValue;

To erase the entry...

_lookupMap.erase( "Some Key Value" );
 
C

Carlos Martinez

Rémi said:
Can someone tell me whether or not my assumptions are good? Just want
to know if I'm going to run into trouble in how I'm deleting map
entries. Although I like to think I know my way around C++, I'm not an
STL expert by any stretch.

Here's a bit of code; notes on my assumptions follow:


_lookupMap is defined as:

map<string, long> _lookupMap;

I'm adding to it something like this:

string * newKey = new string("Some Key Value");
_lookupMap[*newKey] = someIntegerValue;

map copies newKey object for store it. You don't need to create newKey
in the heap, and you are the owner of newKey (not _lookupMap). Then you
must delete newKey.
...and I'm deleting an entry like this (no error checking, assume
find() does actually find...):

string origKey = "Some Key Value";
map<std::string, Int32>::iterator oldEntry = _lookupMap.find(origKey);
const string oldKey = oldEntry->first;
_lookupMap.erase( origKey );


I'm wondering... Will the map object cleanup the string key, or do I
need to delete it myself? Given that the string object is created on
the heap but dereferenced when used as a key, I would assume that the
call to erase will cleanup the string object itself, and I just need to
make sure there aren't any other pointers to the object left lying
around.

Call to erase will cleanup the string inside the map, not the one you
have created (newKey).
 

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

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,294
Latest member
LandonPigo

Latest Threads

Top