標籤:

reinterpret_cast把const string*轉換成const char*出錯?

問題已經解決了,謝謝各位

原代碼是沒有錯,我根據自己的理解擅自把sizeof(string)改成了sizeof(k),實際上原代碼求的是字元串k本身的哈希值,而不是字元串數組的。

假設兩個string都定義成「abc」,但兩個「abc"其實在內存的不同位置。string對象中包含的可能是指向」abc「的指針以及其它成員,所以兩個string用原代碼求出的hash結果也是不同的。

我一開始對這一點趕到疑惑,覺得兩個string調用的結果應該是一樣的,就擅自改成了sizeof(k),結果當然也不對,就導致了下面的問題。

unsigned hash(const string k) {
unsigned int hashValue = 0;
const char *keyp = reinterpret_cast&(k);
for (size_t i = 0; i &< sizeof(k); i++) { hashValue = 37 * hashValue + keyp[i]; } /* for (auto i : k) { hashValue = 37 * hashValue + i; } */ return hashValue; }

用注釋里的for( : )代碼就沒有問題,每次運行得到的hash結果都一樣。

但是用上面的的代碼,每次運行的hash結果都不一樣,簡單查了一下,發現const char *keyp = reinterpret_cast&(k)這句出現了問題,得到的指針keyp並不能實現對字元串k中字元的遍歷,會出現亂碼。

為什麼c++11標準下用reinterpret_cast把const string*轉換成const char*類型得不到想要的結果?

希望大神們解答一下,謝謝!


string不是char

所以const string*不能轉成const char*


reinterpret_cast的語義是將某個值重新解釋,放在這個場景里就是把某塊本來是string的內存區域看做了char數組,應該是直接用c_str()直接獲得string內含的char數組


假設 string s = "abc"; 。

reinterpret_cast&<&>並不是把string的『"abc"』部分轉成字元數組,而是把string這個對象所直接包含的空間里的每一個位元組遍歷一遍。而這個空間未必一定包含著"abc",很可能只是包含了一個『指向"abc"的空間的指針』。於是你用這種方式遍歷一遍的時候,只遍歷到了這個指針的值本身,也就是"abc"所在的地址。

即便有兩個string包含了相同的字元串,這些字元串實際在內存中存儲的位置也通常是不同的,那麼用reinterpret_cast來求hash得到的結果當然也是不同的。

而注釋中的遍歷方法,即range-based for,由於實際上是通過begin()和end()兩個迭代器來進行遍歷的,這樣就是真的在遍歷其字元內容部分了。


string不是char


你這代碼是對 string 本身的對象表示求哈希,而非對字元串……


reinterpret_cast僅限於重解釋而已,要求用戶明確知道兩種類型是可轉類型才可使用。你的string是個obj 沒辦法轉到char*啊。

並且string可以類比char*,你string*類比char*幾個意思?


推薦閱讀:

為什麼用了using namespace std會報錯?
c++如何在編譯期判斷一個對象是否是字元串字面值?
C++的std::thread是怎麼進行參數傳遞的?
怎麼正確書寫C++高階函數?

TAG:C | CC | CPrimer | C11 |