2013-10-14 62 views
2

鑑於以下代碼:非空終止陣列++

#include<iostream> 
int main(){ 
    char container[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; 
    for(char* cptr = container; *cptr != 0; cptr++) 
    std::cout << *cptr << std::endl; 
    return 0; 
} 

它在序列中的每個予執行它一次打印這些字符。我不明白爲什麼循環會終止,因爲我沒有在容器數組末尾明確指定任何空終止符。請幫忙。

+0

它應該會導致分段錯誤 – Kunal

+3

根據環境的不同,您的容器之後的內存可能會用零初始化,導致空終止符發生在那裏。然而,這是不能保證的,所以它可能發生在另一臺機器上/不同的編譯器設置/不同的事情上。 –

+0

未定義的行爲,您可以預測運行時的代碼行爲。 –

回答

8

這只是運氣,真的。

碰巧對應於container[7]的內存區域爲0,所以你越來越幸運了。

超出數組範圍是未定義的行爲。就你而言,它恰好是你所希望的行爲,但你不能依賴它。

+1

+但'幸運'應該''不幸';)它是不值得的情況下最好的。 –

+2

@GrijeshChauhan Heh。我沒有說「祝你好運」或「運氣不好」。 Sidharth--這是好運,「你的代碼就像你喜歡的那樣工作!」這是不幸的,因爲如果/當你移動到任何其他系統時,你會得到一個沒有出現在你的系統上的錯誤,所以很難追查到。 –

+0

@ Scott :):).... –

2

您正在運行調用未定義行爲的數組末尾。一種可能的未定義的行爲是它以一種看似合理的方式工作。在這種情況下,可能發生的情況是未定義的行爲是用零填充你的數組。

1

您正在喚起未定義的行爲。未定義的行爲意味着「任何事情都可能發生」,其中有時包括你想要發生的事情。這就是這裏發生的事情。

調用未定義行爲的原因是因爲當您訪問元素container的末尾時,您正在從未初始化的內存中讀取數據。

3

首先,您發佈的代碼有一個可怕的bug:cptr != 0應該是*cptr != 0。您應該檢查給定地址處的字符是否爲空,而不是指針本身爲空。

其他答案和評論是正確的。獲得正確輸出的唯一原因是因爲在容器數組的末尾碰巧存在一些歸零內存。把container陣列的內部結構將有助於消除微胖編譯器可能會以其他方式插入:

#include<iostream> 
int main(){ 
    struct { 
    char container[7]; 
    char alphabet[27]; 
    } x = { 
    {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    }; 
    for(char* cptr = x.container; *cptr != 0; cptr++) 
    std::cout << *cptr << std::endl; 
    return 0; 
} 

如果您運行此版本中,你會看到你的陣列'a' - 'g'印刷,那麼它會跑過來進入第二個數組並打印'A' - 'Z',然後敲擊該字符串末尾的空值。

+0

cptr!= 0是一個錯字 –

+2

@sidharthsharma - 將來您可以測試您發佈的代碼以避免此類錯別字。至少有一位其他評論者試圖運行您發佈的代碼時感到困惑。 – DaoWen