C++ map的有趣问题<;字符*,整数>; char*a=“aaa”; 地图m; m、 插入(对(a,5)); a[0]=“c”; a[1]=‘c’; a[2]=‘c’; cout
实际上它没有通过“aaa”或“ccc”找到节点,而是通过C++ map的有趣问题<;字符*,整数>; char*a=“aaa”; 地图m; m、 插入(对(a,5)); a[0]=“c”; a[1]=‘c’; a[2]=‘c’; cout,c++,C++,实际上它没有通过“aaa”或“ccc”找到节点,而是通过a指向的内存地址找到节点。指针之间的比较就是这样,它不执行字符串比较。如果你想用一个字符串来索引,那么就用一个std::string我没有正确理解这个问题。尽管如此,在您的代码中,我还是想对一些事情发表评论,例如: char* a = "aaa"; map<char*, int> m; m.insert(pair<char*, int>(a,5)); a[0] = 'c'; a[1] = 'c';
a
指向的内存地址找到节点。指针之间的比较就是这样,它不执行字符串比较。如果你想用一个字符串来索引,那么就用一个std::string
我没有正确理解这个问题。尽管如此,在您的代码中,我还是想对一些事情发表评论,例如:
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`?
这是不赞成的。您的编译器没有发出警告消息吗?应写为:
char* a = "aaa";
正是因为您不应该这样做,所以您的代码中
a
的声明被弃用。如果您按照我的建议声明a
(这也是正确的),那么编译器将为上述赋值语句提供错误
此外,如果a
是const char*
,那么您的问题“节点的左边是ccc还是aaa?”将不会首先出现。因为a
毕竟指向const
数据,所以您无法更改它,因此m.begin()->first
始终是aaa
此外,map
声明应为:
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`
map-m;
或者更好的办法是:
map<const char*, int> m;
map-m;
字符串literal“aaa”
的类型是常量字符[4]
。尽管a
的类型是char*
(指向可修改的char的指针),但您已将其指向只读内存位置
行a[0]=“c”代码>调用未定义的行为,并且在大多数编译器上调用运行时故障
显然,您的编译器允许您的程序以这种方式修改文本“aaa”
的值,以便将值“ccc”存储在其内存位置。但是,当您要求编译器稍后再次生成指向“aaa”
的指针时,它在其静态数据部分生成了它认为是字符串“aaa”的相同地址,问题非常不清楚。您正在尝试修改只读字符串文字。结果将是未定义的行为。我没有完全理解你的答案。;)@蒙托:谢谢你的编辑。我也编辑了它。希望您现在能理解。;-)char*a和m[“aaa”]应该有不同的内存地址,那么如何通过内存地址找到节点?@user956159:不,不能保证它们会有不同的内存地址。字符串文字是不可变的,因此编译器可以使它们都指向相同的内存,但也不一定要指向相同的内存。
map<const char*, int> m;
map<std::string, int> m;