2011-09-21 76 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」相同的地址,即

相關問題