2011-09-21 72 views
-5
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地图<char*, int>

+3

问题很不清楚。 – Nawaz

+1

@Nawaz有问题吗? –

+1

您试图修改只读字符串文字。结果将是未定义的行为。 –

回答

4

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

+0

char * a和m [“aaa”]应该有不同的内存地址,那么如何通过内存地址找到该节点? – user956159

+0

@ user956159:不,不能保证它们具有不同的内存地址。字符串文字是不可变的,所以编译器可以使它们都指向相同的内存,但它不一定。 –

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在代码中declaraton已被弃用。如果您按照我的建议声明a(这也是正确的),那么编译器会为上述赋值语句提供错误

此外,如果aconst char*,那么你的问题“该节点的左边是ccc或aaa?”首先不会出现。因为a毕竟指向const数据,所以你不能改变它,因此m.begin()->first将永远是aaa

此外,map声明应该是:

map<const char*, int> m; 

甚至更​​好的方式是这样的:

map<std::string, int> m; 
+0

我不明白你的答案。;) –

+1

@muntoo:感谢您的编辑。我也编辑它。希望你现在明白。 ;-) – Nawaz

1

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

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

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

相关问题