簡體   English   中英

在C中,在Linux中工作,何時超出范圍訪問數組會導致段錯誤?

[英]In C, working in Linux, when will accessing arrays out of bounds cause a seg fault?

如果我在Linux(和Windows,也許還有所有東西,但我應該清楚)中訪問數組,則有時可以在那里訪問內存,有時可以立即進行段錯誤。 我想知道段錯誤的條件是什么,為什么不一直觸發它? 這是我的猜測,如果有人可以確認或拒絕:

內存以頁面粒度分配給進程,這在x86上為4KiB(無論如何是32位,不確定大約64位)。 因此,從理論上講,只要我停留在當前頁面內,我就應該能夠訪問數組之外​​的任何內容,並且甚至不會引發異常。

接下來,如果我超出4KiB邊界訪問,這可能是我在訪問已屬於程序,並很好地映射到實際的物理存儲位置在我的虛擬地址空間中的內存。 再一次,因為該內存最初是我的,所以沒有發生任何問題(嗯,發生問題的原因是我訪問的范圍超出限制,但是沒有發生操作系統異常)。

在另一方面,如果我的數組訪問試圖訪問我的進程的限制內核部分,我明白即使它映射到物理內存的內存段錯誤的異常。

最后,如果我要訪問虛擬地址空間中存在的內存,但還沒有物理內存,則有兩種情況:

1)我非常不幸,我碰巧要處理一塊內存,該內存在二級存儲中存在一個有效頁面,因此頁面錯誤異常只會加載新頁面,而且我可以繼續訪問

2)更有可能,我嘗試在沒有有效頁的虛擬地址空間中訪問一塊內存,因此現在MMU拋出seg錯誤。

是這樣嗎? 還有更多條件嗎?

您涵蓋了大部分內容。 我能想到的唯一其他事情與一般保護錯誤有關,例如:您越過了頁面邊界,即使該頁面有效且已映射,它也未標記為可讀/可寫,該頁面包含代碼而非數據,等等。 ...

發生了一系列的事件。 作為C編程語言(及其派生語言)的可憎性不對數組進行范圍檢查。

(現在假設您正在進行數組邊界之外的訪問)

因為內存管理基於頁面,所以只要您不越過頁面邊界,任何東西都可以以陣列實際內存允許的任何方式訪問內存。

如果確實超過頁面邊界,則處理器必須轉到頁面表

  1. 該頁面可能沒有頁面表條目。 =>訪問沖突
  2. 該頁面可能有一個頁面表條目,並且未映射。 =>訪問沖突
  3. 該頁面可能被限制為更高的訪問模式(例如,內核,主管,主管)。 如果是這樣,則=>訪問沖突。
  4. 您可以嘗試以不允許的方式訪問該頁面(例如,寫入只讀頁面)。 如果是,則=>訪問沖突

如果您嘗試訪問的邏輯頁面具有映射,並且您嘗試以允許的方式訪問它,那么您可以將自己掛在C中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM