4 回答

TA貢獻2016條經驗 獲得超9個贊
分段錯誤是由訪問“不屬于您”的內存引起的一種特定錯誤。它是一種幫助機制,可以防止破壞內存并引入難以調試的內存錯誤。每當你得到一個段錯誤時,你就知道你正在做一些錯誤的內存 - 訪問已經被釋放的變量,寫入內存的只讀部分等。在大多數(shù)語言中,分段錯誤本質上是相同的,讓你搞砸了在內存管理方面,C和C ++中的段錯誤沒有主要區(qū)別。
有很多方法可以獲得段錯誤,至少在C(++)等低級語言中。獲取段錯誤的常用方法是取消引用空指針:
int *p = NULL;*p = 1;
當您嘗試寫入標記為只讀的內存部分時,會發(fā)生另一個段錯誤:
char *str = "Foo"; // Compiler marks the constant string as read-only*str = 'b'; // Which means this is illegal and results in a segfault
懸空指針指向一個不再存在的東西,就像這里:
char *p = NULL;{ char c; p = &c;}// Now p is dangling
指針p
懸空,因為它指向c
塊結束后不再存在的字符變量。當你試圖取消引用懸空指針(如*p='A'
)時,你可能會得到一個段錯誤。

TA貢獻1816條經驗 獲得超4個贊
值得注意的是,分段故障不是由直接訪問另一個進程內存引起的(這是我有時聽到的),因為它根本不可能。對于虛擬內存,每個進程都有自己的虛擬地址空間,并且無法使用任何指針值訪問另一個進程。對此的例外可以是共享庫,它們是相同的物理地址空間,映射到(可能)不同的虛擬地址和內核內存,甚至在每個進程中以相同的方式映射(以避免系統(tǒng)調用上的TLB刷新,我認為)。像shmat這樣的東西;) - 這些是我所謂的'間接'訪問。但是,可以檢查它們通常位于遠離過程代碼的位置,我們通常能夠訪問它們(這就是它們存在的原因,
但是,如果以不正確的方式訪問我們自己的(進程)內存(例如嘗試寫入不可寫空間),則可能發(fā)生分段錯誤。但最常見的原因是訪問虛擬地址空間中未映射到物理地址的部分。
所有這些都與虛擬內存系統(tǒng)有關。

TA貢獻1802條經驗 獲得超6個贊
分段錯誤是由對進程未在其描述符表中列出的頁面的請求,或對其確實列出的頁面的無效請求(例如,在只讀頁面上的寫入請求)引起的。
懸空指針是一個指針,可能指向或可能不指向有效頁面,但確實指向“意外”的內存段。
- 4 回答
- 0 關注
- 1795 瀏覽
添加回答
舉報