2012-06-12 45 views
1

下面的代碼似乎在不應該運行時運行。在這個例子中:能夠訪問索引大於數組長度的元素

#include <iostream> 
using namespace std; 
int main() 
{ 
    char data[1]; 
    cout<<"Enter data: "; 
    cin>>data; 
    cout<<data[2]<<endl; 
} 

輸入一個字符串的長度大於1(例如,「你好」),會產生輸出作爲如果陣列足夠大,以將其保持(例如,「L」)。當它試圖存儲一個比數組長的值時,或者當它試圖檢索一個索引大於數組長度的值時,它不應該拋出錯誤嗎?

+0

它不能保證工作,所以你不應該依靠這種行爲 – weidi

+0

相關問題:http://stackoverflow.com/questions/1239938/c-accesses-an-array-out-of-bounds-gives-no - 錯誤 - 爲什麼 – nurettin

回答

3

下面的代碼似乎在運行當它不應該

這是「應該」「不應該」。它大約是「可能」「可能不」

也就是說,你的程序可能運行,或者它可能不運行。

這是因爲你的程序調用了undefined behavior。訪問超出數組長度的數組元素會調用未定義的行爲,這意味着會發生任何事情

編寫代碼的正確方法是使用std::string爲:

#include <iostream> 
#include <string> 

//using namespace std; DONT WRITE THIS HERE 

int main() 
{ 
    std::string data; 
    std::cout<<"Enter data: "; 

    std::cin>>data; //read the entire input string, no matter how long it is! 

    std::cout<<data<<std::endl; //print the entire string 

    if (data.size() > 2) //check if data has atleast 3 characters 
    { 
     std::cout << data[2] << std::endl; //print 3rd character 
    } 
} 
+1

聽起來不錯,謝謝一堆。我認爲定義的行爲是切斷字符串或​​拋出異常。感謝您的澄清 – mattsbox

1

它可以根據不同的參數崩潰的編譯或其他機器上編譯,因爲運行的代碼,根據documentaton給出不確定的結果。

1

這樣做並不安全。它正在做的是寫在緩衝區之後的內存中。之後,它會將它讀回給你。

這只是因爲你的cincout操作不說:這是一個字符的指針,我只會寫一個字符。相反,它說:有足夠的空間分配給我寫信。 cincout操作不斷讀取數據,直到它們遇到空終止符\0

爲了解決這個問題,你可以取代這個:

std::string data; 

C++會讓你做出大的內存錯誤。

一些 '規則',將節省您的大部分時間:

1:不要使用char[]。請使用string

2:不要使用指針來傳遞或返回參數。按引用傳遞,按價值歸還。

3:不使用使用數組(例如int[])。使用vectors。你仍然必須檢查你自己的界限。

只有這三個,你會寫一些什麼「安全」的代碼和非C類代碼。

+0

我強烈地試圖爲緩衝區溢出提供一個「分配大數組」的解決方案-1。 – Hurkyl

+0

你想我刪除它嗎? – Rhexis

+0

我認爲這是一個好主意,要麼刪除它,要麼至少引入iostream機制以確保您不會讀取比緩衝區容納的更多字符。我認爲'std :: setw'會在這種情況下工作嗎?我沒有經常使用操縱器進行輸入。 – Hurkyl