基于C語言中段錯(cuò)誤的問題詳解
當(dāng)我在linux下寫c語言的時(shí)候經(jīng)常會(huì)遇到段錯(cuò)誤.
所以就來細(xì)究一下.
段錯(cuò)誤或段違規(guī)(segmentation violation)
查看Expert C Programming(Peter Van Der Linden) Pg.156
解釋到段錯(cuò)誤是由于內(nèi)存管理單元(MMU)的異常所致,
而該異常則通常是由于解除引用一個(gè)未初始化或非法的指針引起.
就是指針正在引用一個(gè)并不位于你的地址空間中的地址.
書中的例子
int *p = 0;
*p = 17;
這里顯然 地址0 并不是你程序所在的地址空間 所能得到的
而我在試驗(yàn)的時(shí)候 幾乎隨便給個(gè)地址 都是段錯(cuò)誤
這也很正常,在運(yùn)行之前是很難知道系統(tǒng)給你分配的地址空間的.
于是我這樣測(cè)試了一下
int *p = 0;
int a = 7;
printf("a addr is %d\n",&a);
scanf("%ld",&p);
printf("%d",*p);
由于 變量a的地址肯定在系統(tǒng)給你的程序所分配的地址空間內(nèi)
所以你按照a的地址 給p賦值
或者小數(shù)目的向上下移4的整數(shù)倍 都是沒問題的
經(jīng)測(cè)試 并無段錯(cuò)誤
分析了一下原因
在linux中,當(dāng)你malloc一段內(nèi)存的時(shí)候 只是拿到了 這段內(nèi)存的虛擬地址.而這段虛擬地址也名沒有實(shí)質(zhì)的映射到物理地址.
而只有當(dāng)你使用這段內(nèi)存的時(shí)候.系統(tǒng)會(huì)申請(qǐng)相應(yīng)頁表映射到相應(yīng)的物理地址.
而*p直接隨意指向一個(gè)虛擬地址 而這個(gè)虛擬地址并沒有實(shí)際的物理地址與之映射.
這時(shí)候解引用會(huì)在MMU發(fā)出異常,返回到linux就會(huì)給用戶報(bào)一個(gè)段錯(cuò)誤.
而如果你定義1個(gè)int型變量 這個(gè)應(yīng)該是一個(gè)棧地址 內(nèi)核已經(jīng)把它映射到一個(gè)實(shí)際的物理頁
你在這個(gè)基礎(chǔ)上小幅度上下偏移地址.相應(yīng)的都應(yīng)該有物理地址與之映射.
自然沒有問題.
以上都是自己的個(gè)人理解.可能還有不足的地方.
歡迎大家交流指教!
相關(guān)文章
opencv實(shí)現(xiàn)像素統(tǒng)計(jì)的示例代碼
本文介紹了OpenCV中統(tǒng)計(jì)圖像像素信息的常用方法和函數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01
QT編寫地圖實(shí)現(xiàn)設(shè)備點(diǎn)位的示例代碼
在地圖應(yīng)用的相關(guān)項(xiàng)目中,在地圖上標(biāo)識(shí)一些設(shè)備點(diǎn),并對(duì)點(diǎn)進(jìn)行交互這個(gè)功能用的最多的,于是需要一套機(jī)制可以動(dòng)態(tài)的添加、刪除、清空、重置。本文將詳細(xì)介紹這些功能如何實(shí)現(xiàn),需要的可以參考一下2022-01-01
visual?studio?2022一個(gè)不易發(fā)現(xiàn)的問題
本文主要介紹了visual?studio?2022一個(gè)不易發(fā)現(xiàn)的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07

