[英]C - Off by one error, but no segmentation fault?
我最近用C編寫了這段代碼:
#include <stdio.h>
#define N_ROWS 100
int main() {
char *inputFileName = "triangle_data.txt";
FILE *inputFile = fopen(inputFileName, "r");
if (inputFile == NULL) {
printf("ERROR: Failed to open \"%s\".\n", inputFileName);
return -1;
}
int triangle[(N_ROWS*(N_ROWS+1))/2 - 1];
size_t size = sizeof(triangle)/sizeof(int);
size_t index;
for (index = 0; !feof(inputFile); ++index) {
fscanf(inputFile, "%d", &triangle[index]);
}
return 1;
}
由於N_ROWS*(N_ROWS+1))/2
只是足夠的空間來保存文件中的數據,因此一直期待着Segmentation Fault
,但是如您所見,我將數組縮小了一個元素。 不知何故,這不會觸發分段錯誤。 如果我將for
-loop的主體替換for
:
int tmp;
fscanf(inputFile, "%d", &tmp);
triangle[index] = tmp;
這里發生了什么。 如果我將數組中的三個元素縮小,它仍然不會觸發分段錯誤。 小觸發的五個要素。 我確定文件中有足夠的數據。
作為測試,我隨后打印了陣列,如果選擇較小的陣列,則缺少元素。
這是怎么回事
PS:在OS X上與clang
一起編譯。
這是怎么回事
在數組對象之外編寫程序時,程序將調用未定義的行為。 C語言中未定義的行為是未定義的,您的程序今天可以正常工作,並且在接下來的幾天中都崩潰,甚至可以打印莎士比亞的完整著作。
分段錯誤並不意味着您訪問了一個數組,而是意味着您訪問了一個未映射的虛擬內存地址。 通常,超出范圍訪問數組會導致這種情況,但是僅僅因為您沒有看到段錯誤,並不意味着您所有的內存訪問都是有效的。
至於為什么看到不同的行為,很難說,並且當結果指定為undefined時,並不一定值得花費時間來證明不同的結果。 如果您真的對正在發生的事情感到好奇,可以查看由兩個版本的代碼生成的程序集(對clang使用--save-temps
參數)。
程序的行為(超出范圍訪問數組元素)是不確定的。
沒有特別要求未定義的行為會導致分段錯誤或任何其他可觀察到的錯誤情況。
從字面上看,未定義的行為意味着C標准不對允許發生的行為施加任何限制。 這意味着任何事情都可能發生,包括看起來工作正常,或者在一種情況下工作,而在另一種情況下工作。
訣竅是不必擔心分段錯誤(或未定義行為的任何實例可能觸發的任何其他錯誤情況)的特殊潛在原因。 這是為了確保程序具有明確定義的行為,因此可以保證不會出現此類症狀。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.