Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » STL and the map template

Credits go to BAF and X-G for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
STL and the map template
Don Freeman
Member #5,110
October 2004
avatar

Ok...I've not really ever messed with the STL map template, so I may be doing this wrong...

My problem is that the destructor for Tile is NOT being called! I have read the description for map, but it does not call the destructor(s) as it should for some reason!

1#include <map>
2using std::map;
3using std::pair;
4enum TerrainTypes
5{
6 Terrain_Plains,
7 Terrain_Forest,
8};
9class Tile
10{
11public:
12 Tile()
13 {
14 type = Terrain_Plains;
15 printf("Tile created.\n");
16 }
17 ~Tile()
18 {
19 printf("Tile destroyed.\n");
20 }
21 enum TerrainType type;
22 BITMAP *image;
23};
24class Map
25{
26public:
27 Map()
28 {
29 Tile *pTile = new Tile;
30 pTile->type = Terrain_Forest;
31 tiles.insert ( pair<int,Tile*>(0,pTile) );
32 printf("size of tiles<int,Tile*>: %i\n",tiles.size());
33 tiles.clear();
34 printf("After CLEAR()...size of tiles<int,Tile*>: %i\n",tiles.size());
35 }
36 ~Map()
37 {
38 tiles.clear();
39 }
40 map<int,Tile*> tiles;
41};

Probably something I've done that is stupid....hehehe ::)

As always...Thanks in advance,
Donald

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

BAF
Member #2,981
December 2002
avatar

IIRC, clear just clears the map, not calling the destructor or anything. You will have to iterate through the map yourself, deleting each pointer stored.

Don Freeman
Member #5,110
October 2004
avatar

map-C++ Reference said:

Clear content

All the elements in the container are dropped: their destructors are called, and then they are removed from the container, leaving it with a size of 0.

Maybe I am just confused as to what/who's destructor clear is calling????

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

BAF
Member #2,981
December 2002
avatar

A pointer doesn't have a deconstructor though. If they were just tiles (not tile*s) then it would work as you are expecting.

Don Freeman
Member #5,110
October 2004
avatar

So...the clear function does not dereference the pointers (as in this case?)

How would I add elements to the map without having to worry about them going out of scope?

...
void SomeFunction( map<int,Tile> &tiles )
{
   Tile aTile;
   tiles.insert(pair<int,Tile>0,aTile);
}
...

Would that be acceptable? I thought that since this would go out of scope, the map class would not contain valid data anymore...or is it that it is calling a copy constructor for the temporary?

[Edit 1]
Ok...I tryed this, it is ok...but calls the copy constructor...how do you avoid that? Using references/pointers....which is where I am at in the beginning... :(
[/Edit]

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

That's right. If you had been storing objects instead of pointers, the destructors would've been called; but the way you've done it now, you need to go through it.

EDIT: As for your reply there, yes, that's valid. There'll be a copy of the object in the map.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Don Freeman
Member #5,110
October 2004
avatar

Thanks to all...

I get confused with pointers every once in a while for some stupid reason.... I don't know why I let them confuse me so... ::)

Working insert without calling copy constructor:

  Tile pTile;
  pTile.type = Terrain_Forest;
  tiles.insert ( pair<int,Tile*>(0,&pTile) );
  printf("size of tiles<int,Tile*>: %i\n",tiles.size());
  tiles.clear();
  printf("After CLEAR()...size of tiles<int,Tile*>: %i\n",tiles.size());

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

Uh... that's not a good idea. That's an access violation waiting to happen.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

BAF
Member #2,981
December 2002
avatar

That's going to give you invalid pointers as soon as pTile goes out of scope. The easiest solution, IMO, would be to do what you were doing before and just to iterate the map and delete each object.

Don Freeman
Member #5,110
October 2004
avatar

I was hoping for some kind of "automatic" cleanup when the map object goes out of scope, but I guess I'll have to manually delete all the objects....damn!

Again, Thanks to X-G and BAF,
Donald

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

There is such a thing: store objects instead of pointers. :P

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Don Freeman
Member #5,110
October 2004
avatar

Ok then...two part question...

One...how would I do THAT (store objects instead of pointers)?
Two...would this be correct (from code before):

  map<int,Tile*>::iterator it;
  for ( it=tiles.begin(); it != tiles.end(); it++ )
  {
      delete (&it);
  }

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

1) map<int, Tile> :P

2) No. delete (*it);

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Don Freeman
Member #5,110
October 2004
avatar

I tried your delete (*it)...I got this error:

error: type ‘struct std::pair<const int, Tile*>’ argument given to ‘delete’, expected pointer

Second:
As for your adding object code...I get multiple calls to the copy constructor and then therefor multiple calls to the destructor. I don't really want that:

  Tile pTile;
  pTile.type = Terrain_Forest;
  tiles.insert ( pair<int,Tile>(0,pTile) );
  printf("size of tiles<int,Tile*>: %i\n",tiles.size());
  tiles.clear();
  printf("After CLEAR()...size of tiles<int,Tile*>: %i\n",tiles.size());

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

Quote:

I got this error:

Oops, sorry. I keep forgetting that map iterators aren't like the other ones. I think it's i->second() or something like that. Check the manual.

Quote:

I don't really want that:

There's no way around it. Write your constructors and destructors to cope with it.

(Also, maps overload the [] operator: tiles[0] = Tile(...);)

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Don Freeman
Member #5,110
October 2004
avatar

Well, for just one add operation...I get 5 calls to the destructor on exit! That seems like crap! I might just end up using a list instead. :'(

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

X-G
Member #856
December 2000
avatar

Lists aren't all that much better. You're still going to have to write proper ctors/dtors... that goes for all STL types.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Don Freeman
Member #5,110
October 2004
avatar

Yeah....noticed that with the list class as well... Damn it...I don't like all the extra calls to the copy constructor and the extra calls to the destructor....such is life I guess....Thanks for the help X-G! ::)

--
"Everyone tells me I should forget about you, you don’t deserve me. They’re right, you don’t deserve me, but I deserve you."
"It’s so simple to be wise. Just think of something stupid to say and then don’t say it."

Kibiz0r
Member #6,203
September 2005
avatar

Why were smart pointers not mentioned, this whole time?

You want a pointer that will call the destructor of the object that it points to as soon as it goes out of scope, yeah?

y halo thar, Smart Pointers. (part of Boost)
http://www.boost.org/libs/smart_ptr/smart_ptr.htm

Edit: Oh, okay, nevermind, cookies were already given. Then I retract my help, seeing as it's not wanted. ;)

Carrus85
Member #2,633
August 2002
avatar

Kibiz0r: I'm guessing because smart_ptr isn't part of the standard library (auto_ptr is, but it doesn't like being placed into a container).

Kibiz0r
Member #6,203
September 2005
avatar

Well, you can write your own template easy enough.

gillius
Member #119
April 2000

I second the smart pointer solution. Spending so much time to avoid using a tool that works...

Gillius
Gillius's Programming -- http://gillius.org/

X-G
Member #856
December 2000
avatar

I figure it was a good opportunity for him to learn how these things work.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

I figure it was a good opportunity for him to learn how these things work.

I for one agree with you.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

Also, maps overload the [] operator:

tiles[0] = Tile(...);

Insert is a bit faster I think (depending on the speed of your default ctor).

tiles.insert ( pair<int,Tile>(0,pTile) );

Its a bit easier / cleaner to use make_pair

tiles.insert ( make_pair(0,pTile) );

Quote:

auto_ptr ... doesn't like being placed into a container.

Hm? I was always under the impression that it would go into a container just fine.

 1   2 


Go to: