about stl map class

B

blackbiscuit

Dear all,

Now I am confused by a problem. I have defined a map object.

map< const char*, int > maps;

then I add one value into maps.

maps[ "June" ] = 1;

Later, I have another char*.

char* p = "June";

And I have maps[ p ] == 1.

Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?

Thank you very much!

Best Wishes,
Tony
 
I

Ian Collins

blackbiscuit said:
Dear all,

Now I am confused by a problem. I have defined a map object.

map< const char*, int > maps;

then I add one value into maps.

maps[ "June" ] = 1;

Later, I have another char*.

char* p = "June";

And I have maps[ p ] == 1.

Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?

It can't, unless you use the exact same string literal.

Use std::string for your key.
 
B

blackbiscuit

blackbiscuit said:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?

It can't, unless you use the exact same string literal.

Use std::string for your key.

Seems I got the answer. The C++ compiler first creates the "June" as a
constant string on the stack. And then the pointer p is pointed to
that constant string. So, now the "June"'s address is as similar as p.
 
I

Ian Collins

blackbiscuit said:
blackbiscuit said:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?
It can't, unless you use the exact same string literal.

Use std::string for your key.

Seems I got the answer. The C++ compiler first creates the "June" as a
constant string on the stack. And then the pointer p is pointed to
that constant string. So, now the "June"'s address is as similar as p.

All the compiler is doing is using the same string literal (where it is
is irrelevant, but it's unlikely to be on the stack). Some compilers
will, others may not.
 
N

Neelesh

blackbiscuit said:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?
It can't, unless you use the exact same string literal.
Use std::string for your key.

Seems I got the answer. The C++ compiler first creates the "June" as a
constant string on the stack. And then the pointer p is pointed to
that constant string. So, now the "June"'s address is as similar as p.

Whether all string literals are distinct or not is implementation
dependent. Which effectively means that
int main()
{
const char* p = "June";
const char* q = "June";
bool eq = p == q;
}

Whether "eq" is true or false is implementation dependent. so in the
current case whether map[p] will be same as map["June"] is
implementation dependent. Not just that, even the output of following
code is implementation dependent

#include <map>
#include <iostream>
int main()
{
std::map<const char*, int> m;
m["June"] = 5;
std::cout << m["June"] << std::endl; //Is the string literal
"June" on this line same as string literal "June" on the previous
line? Implementation dependent.
}
 
W

woodbrian77

blackbiscuit said:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?

It can't, unless you use the exact same string literal.

Use std::string for your key.

I'd use flex_string --
http://erdani.org/code/main.html.

And I'd probably replace the map with a
boost::intrusive::rbtree --
http://www.boost.org/doc/libs/1_39_0/doc/html/intrusive.html.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net
 
I

Ian Collins

blackbiscuit said:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?
It can't, unless you use the exact same string literal.

Use std::string for your key.

I'd use flex_string --
http://erdani.org/code/main.html.
Why?

And I'd probably replace the map with a
boost::intrusive::rbtree --
http://www.boost.org/doc/libs/1_39_0/doc/html/intrusive.html.

Why?
 
W

woodbrian77

blackbiscuit wrote:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?
It can't, unless you use the exact same string literal.
Use std::string for your key.

Why?

According to some tests done by Hartmut Kaiser, replacing std::string
with flex_string in Boost Wave improved performance. My own tests
have also confirmed those results. Flex_string is billed as a "drop-
in-replacement" of std::string and it lives up to that as far as I
can tell. I don't need the "flex" part of flex_string so far, but
it's nice to have it available just in case.


There are a number of reasons on this Boost page --
http://preview.tinyurl.com/r8b37g

In general, I use std::vector and std::deque, and the
Boost Intrusive containers. I've thought for a number of
years that std::map was badly flawed --
http://webEbenezer.net/take4. It's great to have
boost::intrusive::rbtree now to start filling the gap.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net
 
B

blackbiscuit

blackbiscuit wrote:
Dear all,
Now I am confused by a problem. I have defined a map object.
map< const char*, int > maps;
then I add one value into maps.
maps[ "June" ] = 1;
Later, I have another char*.
char* p = "June";
And I have maps[ p ] == 1.
Seems it is trivial. But my problem is the key of maps is const char*
which is a pointer. How can map find the key? Does p has the same
address as the constant "June"?
It can't, unless you use the exact same string literal.
Use std::string for your key.
Seems I got the answer. The C++ compiler first creates the "June" as a
constant string on the stack. And then the pointer p is pointed to
that constant string. So, now the "June"'s address is as similar as p.

Whether all string literals are distinct or not is implementation
dependent. Which effectively means that
int main()
{
const char* p = "June";
const char* q = "June";
bool eq = p == q;

}

Whether "eq" is true or false is implementation dependent. so in the
current case whether map[p] will be same as map["June"] is
implementation dependent. Not just that, even the output of following
code is implementation dependent

#include <map>
#include <iostream>
int main()
{
std::map<const char*, int> m;
m["June"] = 5;
std::cout << m["June"] << std::endl; //Is the string literal
"June" on this line same as string literal "June" on the previous
line? Implementation dependent.

}

So it means to use map in that way is quite dangerous. Is there any
general way to avoid that problem?

Thank you very much!

Best Wishes,
Tony
 

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,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top