2013-07-12 44 views
0

我在下面的代碼中想知道爲什麼i和j的結果是不同的。根據我的直覺,b還指出了值爲4的char地址。爲什麼結果i和j是不同的從char類型轉換爲int類型產生不同的結果

char c='4'; 
const char *b; 
int i,j; 

i=atoi(string(1,c).c_str()); 
b=string(1,c).c_str(); 
j=atoi(b); 
cout<<i<<" "<<j<<endl; 

回答

2

b = string(1,c).c_str();

這將創建一個臨時string的表達後,超出範圍。問題是,只要字符串被調用並且沒有非const函數被調用,那麼由c_str()返回的指針就是有效的。

如果您沿着這條路線行事,您需要確保當您撥打atoi時原始string有效。

std::string s(1,c); 
b = s.c_str(); 
j = atoi(b); 
s.clear(); // b is no longer valid now! 

或者:

j = atoi(string(1,c).c_str()); 
+2

只要字符串,它被稱爲對生命_and_沒有非const函數被調用就可以了。 –

+0

@JamesKanze謝謝,我無恥地編輯了它。 – jrok

+0

它是否在語句'b = string(1,c).c_str()'中表示,該字符串只是一個臨時對象,因此命令'c_str'無效。 – witrus

2

在某些體系結構(os,編譯器,stl實現)中,代碼按預期產生「4 4」。試試吧here

問題是代碼依賴於未定義的行爲,因爲它使用了一個已被銷燬的對象返回的指針。

當編寫

b = string(1,c).c_str(); 

要創建一個臨時對象,並要求它爲一個指向字符數組。您將此指針指定給b,然後臨時對象(擁有內存b現在指向的)被銷燬。假設庫是「理智的」,這種內存將在字符串銷燬期間被釋放。因此通過指針b訪問內存是未定義的行爲。

當然,您不應該依賴未定義的行爲,即使它在某些場合「起作用」。

5
b=string(1,c).c_str(); 

b指向一個臨時對象,該對象在此語句後被銷燬。它實際上有未定義的行爲

轉換字符爲int短的方法是:

int i = c- '0'; 
相關問題