1

在此代碼:puts()如何找到沒有 0終止符的數組的末尾?

int length = atoi(argv[1]); 
char *tab = malloc(length * sizeof(char)); 
memset(tab, '-', length); 
puts(tab); 

無論什麼價值我傳遞給argv[1],輸出是正確的。例如,對於argv[1] = "5"我得到-----(五個連字符)。

我在想如何puts()可以找到輸入字符串的結尾,當我沒有在我的char s數組的末尾加上'\ 0'。

+11

有時未定義行爲似乎工作使用前檢查tab != NULL。只是你的運氣不好。 – aschepler

+1

順便說一句,刪除C++標記 - 這不是(有效的)C++代碼,它是純C – UnholySheep

+1

如果你想糾正它,分配一個額外的字節並添加'*(tab + atoi(argv [1])) ='\ 0';' – byxor

回答

5

@aschepler說什麼。我猜測—或者操作系統或者你的C運行時或者啓動代碼—在你malloc之前正在清零內存。因此,由於您沒有覆蓋已存在的\0字節,因此您的字符串是空終止的。不要以爲這會一直工作!

編輯不同的編譯器,操作系統和庫以不同方式初始化內存。 This question及其答案,同樣this one給出了一些初始化模式和寫入存儲器以幫助調試的其他模式的例子。原來至少一個編譯器(IBM XLC)lets you choose the value for uninitialized automatics.

+1

只是一個想法,但我想知道如果內存被''1''掉了,而不是被清零,或者就此而言,只是填充了非零亂碼)。 – byxor

+1

@byxor [瞧](http://stackoverflow.com/a/127404/2877364):) – cxw

+1

@myschu如果這個答案,或其他,解決了你的問題到你的滿意,請你打對答案旁邊的複選標記接受它?這將有助於這個問題的未來讀者知道什麼對你有用,並將清除沒有接受答案的列表中的問題。你和你接受答案的人也將獲得聲望點:)。 – cxw

0

正如@cxw如上所述,你只是幸運(或您的系統只是在malloc的歸零內存),你的字符串保持其內容後\0

我也想補充一點,你應該不要依賴這樣的方法,因爲它會讓你的程序不穩定並容易崩潰。在這種情況下,你最終會得到一個無效的讀取錯誤,但是如果你的malloc會變大,你會讀取未初始化的內存。

您可能希望使用諸如Valgrind之類的工具來識別內存問題。 請務必記住,在發佈程序之前應修復任何內存錯誤,因爲崩潰很可能取決於程序在其上執行的平臺,還因爲可能會惡意使用此類錯誤。

1

嘗試像0,1,1000,1000000,1000000000,1000000000000,-1這樣的值。

一個從商店偷了幾件東西,並沒有被抓到,這是否偷竊行嗎?嘗試竊取整個商店,看看它是否「有效」。

puts()需要,這意味着一個空字符肯定結束了 - 否則它不是一個。如果代碼違反規則,puts()沒有義務以某種方式行事。它是未定義的行爲(UB)。


BTW,代碼也應在memset(tab, '-', length);

相關問題