Thread: Map containers

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    43

    Map containers

    Hi all

    Yet another thread from your truly... I'm just wondering how I would be able to build a map container so that the elements were placed on the free store instead of the stack? Or does that come as standard with a map container?

    Cheers!

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    That comes with std::map.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    43
    Yes it is part of the standard library, however it's unclear whether the elements are being placed on the stack or in the free store? Pointers to data on the free store appear to be incompatable with map elements... unless someone can explain to me how it's done?!

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Know_Your_Role View Post
    Yes it is part of the standard library, however it's unclear whether the elements are being placed on the stack or in the free store? Pointers to data on the free store appear to be incompatable with map elements... unless someone can explain to me how it's done?!
    I don't know what this question even means. But no, there is no problem with putting pointers to the "free store" (heap memory) into a map. Or any other object.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Why?

    Could you explain, how you would code up a map where the unknown amount of items is stored on the stack?

    Do you know linked list? It's node based. The nodes are in the free store. Same for map.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by anon View Post
    Why?

    Could you explain, how you would code up a map where the unknown amount of items is stored on the stack?
    Well you could pass a custom allocator to the map that allocates on the stack, but I doubt that's what he meant.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    43
    lol I seem to have caused some confusion with this one...

    Consider the following code:

    Code:
    #include <map>
    #include "EOJ_card.h"
    using std::map;
    
    template <class T, class A>
    void RevealDeck (const map <T, A> & deck); 
    
    typedef map<string, Card> deck; 
    
    int main ()
    {
    	deck Attrition;
    	Card *pCard = new Card ("Battle Master", 6, 6);
    	Attrition[pCard->getName()]= *pCard; // surely this is copying the data instead of the address??
    	delete pCard;
    	pCard = 0;
    	cout << "Entire Deck:\n";
    	RevealDeck(Attrition);
    	cout << Attrition["Battle Master"];
    
    	return 0;
    }
    
    template <class T, class A>
    void RevealDeck (const map <T, A> & deck)
    {
    	for (map <T, A>::const_iterator ci = deck.begin(); ci!= deck.end(); ++ci)
    		cout << ci-> second << "\n";
    	cout << endl;
    }
    OK, I have placed a comment where my confusion comes in. If this were a standard array, I would be able to place the address of pointer pCard into the element, therefore ensuring there is no memory leak when the pointer goes somewhere else. To make it clear in case I'm talking nonsense again!, this is what I wanted to do:
    Code:
    Attrition[pCard->getName()]= pCard;
    However when attempting to compile it this way, it returns a compiler error claiming it is unsuitable for conversion.

    In the above code it would appear the data at pCard is copied into the map container element - however this is not what I'm looking for, I'm looking to place the address of the data in. Is there any way this can be done?
    Last edited by Know_Your_Role; 06-10-2009 at 12:54 AM.

  8. #8
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    You need a map of strings and pointers to cards. You can do that:
    Code:
    typedef map<string, Card*> deck;
    The trouble now is clearing all of the memory before the deck is destroyed (because then you'd lose the pointers with which you delete!). Use an auto_ptr, you say. But those don't have the right copy semantics! So it begins!
    Anyway, the above code is what you're looking for. Just remember to delete your cards before the deck goes out of scope.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I think you are going rather over-board here. Don't allocate things dynamically if you don't need to. In this case, is Card a polymorphic type, so you need to store pointers to Cards?

    Code:
    typedef map<string, Card> deck; 
    
    int main ()
    {
        deck Attrition;
        string cardName("Battle Master");  
        Attrition[cardName]= Card(cardName, 6, 6); 
        cout << "Entire Deck:\n";
        RevealDeck(Attrition);
        cout << Attrition[cardName];
    
        return 0;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Registered User
    Join Date
    Mar 2009
    Posts
    43
    Code Monkey - what you're saying makes sense, thanks. However I would not say "use auto_ptr" - since I don't know what auto_ptr is lol.

    How would you suggest the best way is to delete the elements? Could you not just use the same syntax you would to delete all the elements in a standard array? I'm quite new to using containers...

    Cheers :-)

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Know_Your_Role View Post
    How would you suggest the best way is to delete the elements? Could you not just use the same syntax you would to delete all the elements in a standard array? I'm quite new to using containers...
    I think we're getting confused. Your current code stores Cards, not Card pointers. That seems correct. Unless Card is a polymorphic base class, which would be strange, then there is no reason to store the Cards indirectly by pointer.

    Why mess around with dynamic memory when you don't have to?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  12. #12
    Registered User
    Join Date
    May 2009
    Posts
    37
    Quote Originally Posted by brewbuck View Post
    I think we're getting confused. Your current code stores Cards, not Card pointers. That seems correct. Unless Card is a polymorphic base class, which would be strange, then there is no reason to store the Cards indirectly by pointer.

    Why mess around with dynamic memory when you don't have to?
    Well there could be performance related reasons if card were large and you were copying it around a lot, however that may be minimal in this case.

    These days I like use objects with reference counts and smart pointers to go with them for most objects with semi-long life spans. A lot of these types of issues simply vanish when you do this. The main thing you have to watch for is circular references which can be handled by the judicious use of regular pointers where they make sense. For instance in a tree you can use smart pointers with reference counted nodes and if you need parent pointes those can just be regular pointers.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Since a playing card, when it comes down to it, is just a number between 0 and 51, I really don't think there is any performance issue in copying cards.

    My Card class would look like this (minus the other usual things, like comparison operators):

    Code:
    class Card
    {
    public:
        enum Suit { Diamonds, Clubs, Hearts, Spades };
    
        Card( Suit suit, int value )
            : mValue( (int)suit * 13 + value )
        {
        }
    
        Suit GetSuit() const
        {
            return (Suit)( mValue / 13 );
        }
    
        int GetValue() const
        {
            return mValue % 13;
        }
    
    private:
        int mValue;
    };
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The "Battle Master" bit leads me to believe that this isn't your standard 52 card deck.
    But still, storing them by value is a better idea. This is not time-critical code here.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Registered User
    Join Date
    Mar 2009
    Posts
    43
    OK I see your point about passing by value. However, my concern is that I want the data that will be in the elements created on the free store, not the stack. Is that done as standard with map containers anyway or is there a particular syntax I need to use?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Adding a Map to a program
    By Shogun32 in forum C++ Programming
    Replies: 1
    Last Post: 05-04-2009, 09:42 AM
  2. Polynomials and ADT's
    By Emeighty in forum C++ Programming
    Replies: 20
    Last Post: 08-19-2008, 08:32 AM
  3. New editor updates
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-05-2005, 03:26 PM
  4. Creating a map engine.
    By suzakugaiden in forum Game Programming
    Replies: 11
    Last Post: 06-21-2005, 05:06 AM
  5. Searching STL Map Inside STL Map Object :: C++
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 11-14-2002, 09:11 AM