2013-08-21 14 views
1

我昨天開始學習C,所以這可能是一個微不足道的問題,但我仍然不明白。在小數組中排列兩個字符串時的段錯誤

比方說,我有以下代碼:

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    char text[8]; 
    strcpy(text, "Lorem "); 
    puts(text); 
    strcat(text, "ipsum!"); 
    puts(text); 
    return 0; 
} 

這將導致分段故障時(或之後)concating的字符串。但是,如果我將text的大小從8更改爲9,則不會。

請糾正我,如果我錯了,但是這是我的想法是正確的: - !「文字」

「排版」大小6(或7 \ 0)
- 大小6(或7與\ 0)
「Lorem ipsum!」 - 大小12(或13與\ 0)

那麼,8/9從哪裏來?這是由執行strcat引起的嗎?還是有最小數組長度的東西?還是我犯了一個愚蠢的初學者的錯誤?

在此先感謝。

+4

[未定義行爲(http://en.wikipedia.org/wiki/Undefined_behavior) –

+0

運行此Valgrind的下(http://valgrind.org),你會看到有一個問題,在這兩個案例。 – alk

+1

對於你的問題「8/9來自何處」的回答,你的特定編譯器完全有可能以8字節塊爲單位分配內存。所以text [8]會分配8個字節;文本[9]將四捨五入到16個字節。當然這是依賴於實現的,你永遠不應該指望一個編譯器總是這樣做! –

回答

3

它只是純粹的運氣,它沒有崩潰,至少在Linux上我得到*** stack smashing detected ***

即使後者的存儲空間不足,您正試圖將字符串附加到另一個字符串。這是未定義行爲的一個例子(正如評論中指出的那樣)。

C是一種總是信任程序員和程序中的內容的語言,因此編譯時甚至不會收到警告。

請務必確保在緩衝區中有足夠的存儲空間,C中只有很少的設施可以保證安全行爲,所以不要假設如minimum array length

+0

嗯,我認爲這是我應該習慣的,因爲我只有Java和一些腳本語言的經驗。謝謝。 – Griddo

+0

噢,絕對的,Java是非常特別的,例如永遠不會讓你使用單元化的原始類型,而如果你啓用了所有的警告,你可能會在'C'中得到警告,它仍然會讓你運行假設你知道自己在做什麼的代碼:)而且你永遠不會對腳本語言的寬容行爲感到厭倦,這些腳本語言在幕後爲你做了很多。 C非常裸露。 – Nobilis

3

當您溢出數組的末尾時,程序具有未定義的行爲。這意味着它可能做你期望它做的事情或者它可能做不到的事情。它可能會運行,如果你沒有調用未定義的行爲。它可能會崩潰。它可能會重新格式化您的硬盤。它可能會在打印機上打印空白頁面。它可能會完成所有這些事情,具體取決於您何時運行它。

你無法知道。這就是'未定義的行爲'。未定義。

我可以給你一個行爲的解釋,但它是無益的,非常硬件和具體實現。

0

您可以將malloc設置爲任意大小。甚至可以根據進一步的輸入重新分配。

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int main() 
{ 
    char *text; 
    text = (char *) malloc(sizeof(char) * 12); 
    memset(text, 0x0, sizeof(char) * 12); 
    sprintf(text, "%s", "Lorem "); 
    puts(text); 
    sprintf(text, "%s%s", text, "ipsum!"); 
    puts(text); 
    return 0; 
} 
相關問題