Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
auth_update crash
Dec 23, 2017, 10:15 pm
By Remcon
check_tumble
Dec 18, 2017, 7:21 pm
By Remcon
parse description bug
Dec 15, 2017, 10:08 pm
By Remcon
Couple bugs
Dec 12, 2017, 5:42 pm
By Remcon
Bug in disarm( )
Nov 12, 2017, 6:54 pm
By GatewaySysop
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
LOP Heroes Edition
Author: Vladaar
Submitted by: Vladaar
Heroes sound extras
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.3
Author: Vladaar
Submitted by: Vladaar
Users Online
CommonCrawl, Yandex

Members: 0
Guests: 3
Stats
Files
Topics
Posts
Members
Newest Member
478
3,708
19,242
612
Jacki72H
Today's Birthdays
There are no member birthdays today.
Related Links
» SmaugMuds.org » General » Coding » STL Map
Forum Rules | Mark all | Recent Posts

STL Map
< Newer Topic :: Older Topic >

Pages:<< prev 1 next >>
Post is unread #1 May 4, 2011, 9:51 pm
Go to the top of the page
Go to the bottom of the page

Keirath
Magician
GroupMembers
Posts144
JoinedJan 24, 2008

Ok, I have pretty well figured out how std::list works and have moved on to learning maps and what not. I am playing with the alias system AFKMUD has and am trying to put the C++ version into an SWR that doesn't use strings.
Arg and argument are both const char*s.

How would you properly do this:
   ch->pcdata->alias_map[arg] = argument;

       
Post is unread #2 May 5, 2011, 10:12 pm
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

typedef std::map<const char *, const char *> charStarMap;

...
charStarMap alias_map;
...

ch->pcdata->alias_map["booger"] = "pick nose";


Funny you should ask this, as I have a rather interesting problem I ran into while working on the xterm256/rgb color mapping code.
       
Post is unread #3 May 5, 2011, 10:31 pm
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

Here's MY problem:
Colorizereror Code

As you can see from the output below, it recognizes my color code symbols and properly replaces them, however... the mapping ONLY recognizes them when they're passed in as hand-typed quoted string constants. The version passed in that's extracted from a substring match does NOT seem to work.

This is rather puzzling, because there are no compiler errors or warnings. If it were a type mismatch (char * vs. const char *, for example), the compiler should have whined up a shit-storm at me for not having a proper matching function in the map template.

Any suggestions are welcome. I despise C++, but the only other option is C, which would be even worse (no mappings at all, binary search on paired arrays or structures is your only real option).

Source:  [G05]Grey [F034567]Stuff [OliveDrab]Forever [RESET]

found [
translate(xterm-256color, G05)
Found xterm-256color
Found G05
translate(xterm-256color, RESET)
Found xterm-256color
Found RESET
found ]
MATCH: "G05" - 3 3
   at: 0, 4
translate(xterm-256color, G05)
Found xterm-256color
NOT Found G05
REPLACEMENT: "G05" - 3
Result:  G05Grey [F034567]Stuff [OliveDrab]Forever [RESET]

found [
translate(xterm-256color, G05)
Found xterm-256color
Found G05
translate(xterm-256color, RESET)
Found xterm-256color
Found RESET
found ]
MATCH: "F034567" - 7 7
   at: 8, 16
translate(xterm-256color, F034567)
Found xterm-256color
Rendered F011
NOT Found F034567
REPLACEMENT: "F034567" - 7
Result:  G05Grey F034567Stuff [OliveDrab]Forever [RESET]

found [
translate(xterm-256color, G05)
Found xterm-256color
Found G05
translate(xterm-256color, RESET)
Found xterm-256color
Found RESET
found ]
MATCH: "OliveDrab" - 9 9
   at: 21, 31
translate(xterm-256color, OliveDrab)
Found xterm-256color
NOT Found OliveDrab
REPLACEMENT: "OliveDrab" - 9
Result:  G05Grey F034567Stuff OliveDrabForever [RESET]
found [
translate(xterm-256color, G05)
Found xterm-256color
Found G05
translate(xterm-256color, RESET)
Found xterm-256color
Found RESET
found ]
MATCH: "RESET" - 5 5
   at: 38, 44
translate(xterm-256color, RESET)
Found xterm-256color
NOT Found RESET
REPLACEMENT: "RESET" - 5
Result:  G05Grey F034567Stuff OliveDrabForever RESET

Result:  G05Grey F034567Stuff OliveDrabForever RESET

       
Post is unread #4 May 6, 2011, 12:18 am
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

I found the problem. Bonus points to anyone else who can spot it. It's one of the reasons I hate C (and C++). :)

Hint:

02:38 <dchat> Quixadhal: It's like, when are two identical char * arrays not equal?
02:38 <dchat> Quixadhal: Hmmmm, no... could C++ really be THAT stupid? I bet it could.

       
Post is unread #5 May 7, 2011, 3:21 am
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

No guesses?

Awwwwww, you guys aren't trying.
       
Post is unread #6 May 7, 2011, 2:08 pm
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,639
JoinedJan 1, 2002

Nope, no guess here. The hint doesn't help either. I guess we need spoilers :)
       
Post is unread #7 May 7, 2011, 5:04 pm
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

Hehehehe. I realized what it was doing as I typed that, and it's pretty stupid.

When are two identical char * arrays not equal? When they are two different arrays. std::map<const char *, const char *> uses the pointer itself, not the contents of the "string", as the key values.

So, when my code compared the statically assigned foo = "bob" against the extracted substring, they pointed to different memory locations and so were not equal. However, if you use the quoted string "bob" as a constant in several places, the compiler will generate ONE copy and put pointers to it in each of those places that ARE equal, masking the issue.

Very sneaky.

You can avoid the issue by using std::string instead of const char *, but then you have another problem. Bloat. I did that in C++, and then I got annoyed and wrote a C version.

-rwxr-xr-x 1 quixadhal users 3740637 May  6 06:52 testme
-rwxr-xr-x 1 quixadhal users  509667 May  7 06:29 testme2


The C++ version bloats up to be 7X larger *and* it took forever to compile as g++ wanted almost 1.5G of RAM to generate it (my machine only has 768M, so swap city).

In typical usage, this probably isn't an issue, but in my case, I had 11K entries in my mapping, and all those string constructors must have added up!
       
Post is unread #8 May 7, 2011, 5:52 pm
Go to the top of the page
Go to the bottom of the page

Keirath
Magician
GroupMembers
Posts144
JoinedJan 24, 2008

Well, I guess my problem is more whats the best way to create the map and what not. This is what I have for creating/modifying the aliases.
   if( ( al = ch->pcdata->alias_map.find( arg ) ) == ch->pcdata->alias_map.end(  ) )
   {
      send_to_char( "Created Alias.\r\n", ch);
      ch->pcdata->alias_map.insert( std::make_pair( arg, argument ) );
   }
   else
   {
      send_to_char( "Modified Alias.\r\n", ch );
      ch->pcdata->alias_map[arg] = argument;
   }


Is this right? I am having trouble with it actually working too. Basically, I am clueless here. Trying to figure this one out haha.
       
Post is unread #9 May 8, 2011, 1:06 pm
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

In light of my discovery, I'd suggest using std::map<std::string, std::string>, as strings do properly work for comparisons. If you try to use char *'s, it will fail in strange ways.
       
Post is unread #10 May 8, 2011, 1:40 pm
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,639
JoinedJan 1, 2002

Wow. Yep. Another fine example of why hatred for C strings is entirely justified.

11,000 entries? WTF is in that map of yours anyway? Color processing is seriously that big?
       
Post is unread #11 May 9, 2011, 3:59 am
Go to the top of the page
Go to the bottom of the page

Quixadhal
Conjurer
GroupMembers
Posts398
JoinedMar 8, 2005

Hehehehe, well, it is when you want to support a whole bunch of color names for several terminal types. :)

Let's see.... The 16 ANSI colors, 256 xterm names, a handful of control symbols (RESET, CLEARLINE, etc), and then about 350 symbolic names from the /etc/X11/rgb.txt file (colors like GhostWhite, PeachPuff, etc). So around 700 entires for the main mapping. Then there are 7 terminal types (unknown, ansi, xterm-256color, xterm-grey, imc2, i3, and mxp), so that gives us around 5K entries.

Oh, I probably should have said "objects". Each entry is one key + one value, so that's 10K. The other 1K or so is a couple of smaller mappings for things like imc2i3 conversions and the like.
       
Pages:<< prev 1 next >>