4 回答

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

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

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
分段錯(cuò)誤是由對(duì)進(jìn)程未在其描述符表中列出的頁面的請(qǐng)求,或?qū)ζ浯_實(shí)列出的頁面的無效請(qǐng)求(例如,在只讀頁面上的寫入請(qǐng)求)引起的。
懸空指針是一個(gè)指針,可能指向或可能不指向有效頁面,但確實(shí)指向“意外”的內(nèi)存段。
- 4 回答
- 0 關(guān)注
- 1807 瀏覽
添加回答
舉報(bào)