二級指針及段錯誤

首先段錯誤產生的原因有兩個:

1、訪問的內存地址超出了系統給這個變量分配的內存空間(越界)

2、系統訪問了程序的靜態數據區


段錯誤產生的過程是:

1、用戶程序要訪問的一個虛擬地址(VA),經過MMU檢查後發現是無權訪問的

2、MMU產生一個異常,CPU從用戶態切換到特權模式,產生遺產關中斷,並跳轉到內核代碼中執行異常服務程序。

3、內核吧這個異常解釋Wie段錯誤,並把引發段錯誤的進程終止。


下面是自己遇到的例子:

1、我想通過二維指針訪問二維數組的時候,運行期間發生了段錯誤,也就是我訪問了不該訪問的內存空間,代碼如下

編譯出現報警:


運行後出現

原因分析:實質上通過ppArray = array之後,ppArray就是數組array[0][0]的地址了,那麼*ppArray就是array[0][0],值爲7,那麼如果我通過**ppArray操作,則訪問了地址爲7的空間,當然會出現段錯誤。


2、實質上可以直接用一級指針訪問二維數組。


通過這種方式會有警告:


3、我們可以把數組二維數組看爲一維數組內嵌套一維數組,用一級指針指向二維數組array[3][4]的行,代碼如下



4、如果必須要用二級指針訪問二維數組的話,可以藉助指針數組



另外一個常見的段錯誤的例子:

當指針訪問靜態區的時候會出現段錯誤


當前指針指向靜態區的數據"hello",而後我又通過指針往靜態區寫數據,訪問了我不該訪問的地址,必然出現段錯誤。

然而當我通過變量定義

unsigned char *a = "hello";

unsigned char *ptr = a;

ptr = "world";

不會出現段錯誤,因爲ptr = a實現了ptr指向"hello",而ptr本身是存在棧區的

段錯誤的分析辦法:




二級指針的分析:通過棧的操作


如左圖所示:

1main函數壓棧,分配棧空間,創建變量*p,其中,p1000,也就是*p指向地址爲1000的內存空間

2fun函數壓棧,分配棧空間,創建**變量,其中,*p2000,也就是**p指向地址爲2000的內存空間。

3、執行*p = string,而string = 50005000這塊地址存儲的是hello字符串,也就是**p指向存儲"hello"的地址

4fun函數出棧,那麼main函數中的p=5000,也就是*p指向地址爲5000內存(存放的爲hello字符串)

5、程序執行完後應該free(p)


如左圖所示:

1main函數壓棧,分配棧空間,創建變量*p,其中,p1000,也就是*p指向地址爲1000的內存空間

2fun函數壓棧,分配棧空間,創建**變量,其中,*p2000,也就是**p指向地址爲2000的內存空間。

3、執行*p = string,而string = 50005000這塊地址存儲的是hello字符串,也就是**p指向存儲"hello"的地址

4fun函數出棧,那麼main函數中的p=5000,也就是*p指向地址爲5000內存(存放的爲hello字符串)

5、程序執行完後應該free(p)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章