Author Topic: Noob problem with std::map  (Read 36052 times)

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #15 on: October 16, 2015, 02:57:15 PM »
Quote from: TheCreator
However, I can't see a single reason why to use smart pointers (apart from one legitimate use of auto_ptr, but that's another story, I guess).
I'll start with stressing that auto_ptr is one of the few well-known failures of C++. It quickly became obvious it does not fulfill its role and it was promptly deprecated, so I'm afraid there is no legitimate use for it :-) As for the reasons to use smart pointers the main one I believe is a strictly expressed ownership which being checked by the compiler. You can't lose a shared pointer by mistake, you can neither lose nor accidentally copy unique one and you can clearly see from the signature which is which. Also, they integrate seamlessly with value semantics and RAII.

Quote from: TheCreator
It seems that you are talking about C++11 here. Well, everyone knows it has cool features, but unfortunately some people are stuck in the stone age with their Visual Studio 2005 and can't enjoy that coolness.
Well, I do tend to talk about C++11. Which is four years old now and with all major compilers being free it should generally be safe to assume that C++11 is available. It is beside the point of discussion but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

Still, if we are talking about smart pointers, C++11 is not a must. There is also Technical Report 1 which was like a preview of C++11 for long years. There are shared_ptr and weak_ptr in std::tr1 namespace. Though I must admit the language support for them is weaker.

Quote from: TheCreator
As of shared_ptr's usefulness, I'm not convinced. My biggest problem with reference counting are memory leaks. If I forget to free an object which is tied to a complex hierarchy of objects, all those objects fail to release their dynamically allocated memory and I get a giant leak report. It takes ages to investigate which object has caused a leak. Does shared_ptr address this problem?
This, I believe, is more an architectural problem which can happen in any language and with any memory management model. As if you can't end up like this with C.

C++ smart pointers, however, do provide some tools to solve this. Specificly, std::weak_ptr which keeps tabs on the object from std::shared_ptr but does not prevent it from being deallocated. It allows to check whether the object is still alive and get a full std::shared_ptr for it. C++ smart pointers represent various degrees of ownership, with std::unique_ptr being the strongest and std::weak_ptr being the weakest. When all your references are expressed like this, circular references naturally break over difference in levels of ownership. Going with your example about some objects (As) being needlessly held alive by some root (B), if B can function without As then its reference to As is weak and they will be deallocated as intended.
« Last Edit: October 16, 2015, 04:40:19 PM by Cfyz »

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #16 on: October 16, 2015, 04:34:06 PM »
but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

I'm using 2010. The problem with newer versions is that I lost my M$ id and could not recover it. For some reason it was impossible, I don't exactly remember why. What I have heard the newest version is BS anyway.

TheCreator

  • Rogueliker
  • ***
  • Posts: 370
  • Karma: +0/-0
    • View Profile
    • Fame
    • Email
Re: Noob problem with std::map
« Reply #17 on: October 19, 2015, 06:11:05 AM »
I'll start with stressing that auto_ptr is one of the few well-known failures of C++. It quickly became obvious it does not fulfill its role and it was promptly deprecated, so I'm afraid there is no legitimate use for it :-)

This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :).

Quote
It is beside the point of discussion but I am curious why do you still use VisualStudio 2005 when up-to-date versions of this product are available for free.

They require an up-to-date hardware, I'm afraid, and hardware requires an up-to-date Windows version. I'm not a kind of guy that would happily buy all the new stuff every two years or so. I use the old stuff until it breaks down beyond all repair. Of course, this way I cannot participate in the technical revolution, enjoy smart pointers etc., but guess what - it doesn't worry me that much :).
Fame (Untitled) - my game. Everything is a roguelike.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #18 on: October 19, 2015, 10:45:32 AM »
This is only a related question, but why doesn't list or vector like to use the local object form (non-pointer) when the object has a class instance created with new? You know, now that Tile has a terrain object created with new in Tile's constructor it makes this fail:

Code: [Select]
std::vector<Tile> tilemap;

for (c.y=0; c.y<h; c.y++)
{
for (c.x=0; c.x<w;  c.x++)
{
tilemap.push_back(Tile(bt, c));
}
}

But if you would change Tile to Tile* in the vector it would work. It's just going to be so much fun to change all .'s to ->'s in 1600 lines of Tilemap class.

reaver

  • Rogueliker
  • ***
  • Posts: 207
  • Karma: +0/-0
    • View Profile
Re: Noob problem with std::map
« Reply #19 on: October 19, 2015, 12:10:48 PM »
provide a default constructor perhaps?

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #20 on: October 19, 2015, 12:38:13 PM »
More like copy constructor that creates a new instance of that terrain class, because the default copy constructor doesn't make it. This is the problem with std containers that I mentioned earlier, they create a copy of the object. Or then I could change the vector type to Tile* which I think is less painful after all.

TheCreator

  • Rogueliker
  • ***
  • Posts: 370
  • Karma: +0/-0
    • View Profile
    • Fame
    • Email
Re: Noob problem with std::map
« Reply #21 on: October 19, 2015, 12:56:47 PM »
In fact, to comfortably use a class with standard containers you need both copy constructor and default constructor.
Fame (Untitled) - my game. Everything is a roguelike.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #22 on: October 19, 2015, 01:02:37 PM »
Quote
This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :)
Oh yes it will. You are likely to already know, but for the sake of other readers, I'll remind that the main problem with auto_ptr is that its assignment/copy behaviour is literally broken. It actually performs an implicit move instead of a assignment/copy, silently leaving the original empty. Assignment operator not performing assignment, this is a disaster on many levels rendering auto_ptr unusable with standard library (which relies on copying greatly) and prone to counter-intuitive results.

Maybe you are talking about using auto_ptr as a scope-level guard tasked with calling destructor. In this role auto_ptr mainly fails by not providing means to specify a custom deleter. For example, you cannot wrap FILE* or AVFormatContext* in auto_ptr and make it call suitable close function at scope exit (but you can do this with shared_ptr or unique_ptr). This leaves a single scenario where auto_ptr is useful. That would be scope-guarding a temporary polymorphic object dynamically allocated within that scope. This situation is so narrow that I believe (religious, duh!) it is much safer to just outright ban auto_ptr than keep all this quirks in mind. Raw pointers should be better than auto_ptr, if you cannot or refuse to use normal smart pointers.

Quote from: TheCreator
I use the old stuff until it breaks down beyond all repair. Of course, this way I cannot participate in the technical revolution, enjoy smart pointers etc.
There are a few options. If you are not too attached to VisualStudio, there are another IDEs, i. e. Eclipse CDT (quite different but really good after you suffer through a bit). There is also Boost, which is admittedly bloated but you are not compiling by hand and paper, are you? And there is always an option to just copy-paste the relevant source from somewhere. Just saying.

Quote from: Krice
More like copy constructor that creates a new instance of that terrain class, because the default copy constructor doesn't make it. This is the problem with std containers that I mentioned earlier, they create a copy of the object. Or then I could change the vector type to Tile* which I think is less painful after all.
Yes, this is almost certainly a problem with copy constructor not really making a copy. However, this is not a problem with containers but with the class code. By making some container keep references to the objects you will not make you copy constructor behave correctly. Whether you make more problems by using raw pointers or not, you are just masking the problem until the time you'll make a copy, accidentally or not.

I highly encourage you to at least skim through Rules of Three/Five/Zero.

Note that per rule of zero, smart pointers do help here. It is okay to use default copy constructor if pointer is not raw but reference-counted shared_ptr.
« Last Edit: October 19, 2015, 02:57:17 PM by Cfyz »

Xecutor

  • 7DRL Reviewer
  • Rogueliker
  • *
  • Posts: 263
  • Karma: +0/-0
    • View Profile
Re: Noob problem with std::map
« Reply #23 on: October 19, 2015, 02:47:24 PM »
Quote
This sounds like a religious belief. Talk to me like an engineer, not like a priest. Sure, auto_ptr is not a general purpose pointer, but it is working. It won't explode if you try to use it :)
Oh yes it will.
I'll add that:
Code: [Select]
  std::auto_ptr<Object> ptr(new Object[n]);
is also a common mistake with auto_ptr that cannot be solved my means of auto_ptr at all.


Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #24 on: October 20, 2015, 10:04:19 AM »
I need no rules. Anyway, I noticed something interesting when I changed Tile to Tile* in the tile map vector. The size for let's say 100x100 map is of course 10 000 tiles. Now here is the deal: it's slow. Yes. All right then. It's noticeably slow to access the map which can be seen when walking around with (w)alk command. Not only that, it seems to be painfully slow for vector to delete map objects in the destructor. Oh well. I guess it's quite easy to change that vector to raw pointer array. Should be faster. But it's interesting to realize that std::vector is slow, you just don't realize it in most cases. I should actually watch out that, because I also placed tile graphics classes in a vector.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #25 on: October 20, 2015, 11:17:38 AM »
Quote from: Krice
I need no rules.
Stubbornly resolving the trouble you keep bringing upon yourself is a noble, albeit foolish endeavor. You are a chaotic neutral character, aren't you?

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #26 on: October 20, 2015, 12:00:35 PM »
It's easy to change static size vector to array of pointers, but it was only slightly faster. The worst thing is deleting the maps, I tried to enter 4-5 levels and when quitting the game it takes several seconds to delete the objects in maps. Really. It's this slow? Maybe I need to look at the object class hierarchy and try to create a light weight base class for objects, but still.. or maybe I could wait for 10 years for computer power to catch up!

mushroom patch

  • Rogueliker
  • ***
  • Posts: 554
  • Karma: +0/-0
    • View Profile
Re: Noob problem with std::map
« Reply #27 on: October 20, 2015, 03:04:44 PM »
lol you guys are getting trolled so hard..

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #28 on: October 20, 2015, 09:45:03 PM »
Sure.

What I found out is that memory management of lots of small objects is slow I guess. So they say. I just never had that many objects, but now when all terrain tiles are objects the problem is real. Some have solved the problem with some kind of memory manager that allocates a big area of memory and then smaller objects can use that somehow. However first I'm going to try couple of things like removing a std::list item in the base class of objects and see what happens, but I doubt it will change anything.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Noob problem with std::map
« Reply #29 on: October 21, 2015, 07:41:16 AM »
I think the problem is solved. I tried to run the .exe without IDE and it's blazing fast! What I read Visual Studio is using some kind of special memory management in debug mode which seems to be really slow.

Well, it's still a kind of problem, because I'm constantly running the program and testing stuff, so it can become really annoying.
« Last Edit: October 21, 2015, 07:43:14 AM by Krice »