map <char *,int =“”> </char *,>的有趣问题

时间:2011-09-21 05:13:44

标签: c++

char* a = "aaa";

map<char*, int> m;   
m.insert(pair<char*, int>(a,5));    

a[0] = 'c';
a[1] = 'c';
a[2] = 'c';

cout << a << endl; // a = `ccc`
cout << m["aaa"] << endl; // found the node by `aaa`,
cout << m.begin()->first << endl; // but the node's left is actually `ccc`?

所以节点左边是cccaaa

3 个答案:

答案 0 :(得分:4)

实际上它没有通过“aaa”或“ccc”找到节点,它通过内存地址a找到了节点。指针之间的比较就是这样,它不执行字符串比较。如果要按字符串索引,请使用std::string

答案 1 :(得分:4)

我没有正确理解这个问题。尽管如此,我想在您的代码中评论的内容很少,例如:

char* a = "aaa";

这已被弃用。你的编译器没有发出警告信息吗?它应该写成:

const char* a = "aaa";

a[0] = 'c'; //it should be an error if you correctly declare `a`
a[1] = 'c'; //it should be an error if you correctly declare `a`
a[2] = 'c'; //it should be an error if you correctly declare `a`

正是因为你不应该这样做,你的代码中a的声明被弃用了。如果你按照我的建议声明a(这也是正确的),那么编译器会为上述赋值语句提供错误

此外,如果aconst char*,那么您的问题“节点的左侧是ccc还是aaa?”首先不会出现。由于a毕竟指向const数据,因此无法更改,因此m.begin()->first始终为aaa

此外,map声明应为:

map<const char*, int> m;

或者更好的是:

map<std::string, int> m;   

答案 2 :(得分:1)

字符串文字"aaa"的类型为const char[4]。尽管a的类型为char*(指向可修改字符的指针),但您已将其指向只读内存位置。

a[0] = 'c';调用未定义的行为,并且在大多数编译器上调用运行时失败。

显然,您的编译器允许您的程序以这种方式修改文本"aaa"的值,以便将值“ccc”存储在其内存位置。但是,当您要求编译器稍后再次生成指向"aaa"的指针时,它会生成与其静态数据部分中字符串“aaa”相同的地址,