在c程序中,經常會遇到段錯誤(segment error)和總線錯誤(bus error),這兩種問題出現的原因可能如下
- 段錯誤:
- 對一個NULL指針解引用。
- 訪問程序進程以外的內存空間。
實際上,第一個原因可以規約到第二個原因,在一個c程序的虛擬內存空間中,從低地址到高地址一次是代碼區,堆區(向上增長),棧區(向下增長),最上是常量區,其中NULL指針的位置正好是虛擬內存中地址為0的位置,而這個位置是不屬於以上4個區域的,同理一些比較低的地址也不屬於這四個區,所以造成段錯誤的原因是訪問了程序虛擬內存空間4個區以外的地址,在平時的開發中,最大的可能還是對NULL進行了解引用。
- 總線錯誤
- 對一個錯誤的起始地址進行解引用
由於進程的虛擬內存空間實際上是對物理地址的一個映射,操作系統和編譯器會用內存對齊來做優化,通常就是4字節對齊,所以int,float這種類型的起始地址都是4的倍數,而short的起始地址是2的倍數,double的起始地址是8的倍數,假如此時對一個不是4倍數的地址a進行解引用 (int *) a,就可能會出現總線錯誤,這個出現的情況還要具體看是哪一種操作系統。總線錯誤一般不會出現,出現的情況多半是使用了指針的強制轉換。
有了以上分析就能在遇到這些問題時有處理的思路了。