不要傷害指標(6) 指標的安全問題

2022-04-10 15:23:51 字數 1229 閱讀 6073

看下面的例子:

例十八:

char s = 'a'

;int *ptr;

ptr = (int *)&s;

*ptr = 1298;

指標ptr 是乙個int *型別的指標,它指向的型別是int。它指向的位址就是s 的首位址。在32 位程式中,s 佔乙個位元組,int 型別佔四個位元組。最後一條語句不但改變了s 所佔的乙個位元組,還把和s 相臨的高位址方向的三個位元組也改變了。這三個位元組是幹什麼的?只有編譯程式知道,而寫程式的人是不太可能知道的。也許這三個位元組裡儲存了非常重要的資料,也許這三個位元組裡正好是程式的一條**,而由於你對指標的馬虎應用,這三個位元組的值被改變了!這會造成崩潰性的錯誤。

讓我們再來看一例:

例十九:

char

a;int *ptr = &a;

ptr++;

*ptr = 115;

該例子完全可以通過編譯,並能執行。但是看到沒有?第3 句對指標ptr 進行自加1 運算後,ptr 指向了和整形變數a 相鄰的高位址方向的一塊儲存區。這塊儲存區里是什麼?我們不知道。有可能它是乙個非常重要的資料,甚至可能是一條**。而第4 句竟然往這片儲存區里寫入乙個資料!這是嚴重的錯誤。所以在使用指標時,程式設計師心裡必須非常清楚:我的指標究竟指向了**。在用指標訪問陣列的時候,也要注意不要超出陣列的低端和高階界限,否則也會造成類似的錯誤。

在指標的強制型別轉換:ptr1=(type *)ptr2 中,如果sizeof(ptr2的型別)大於sizeof(ptr1 的型別),那麼在使用指標ptr1 來訪問ptr2所指向的儲存區時是安全的。如果sizeof(ptr2 的型別) 小於sizeof(ptr1 的型別),那麼在使用指標ptr1 來訪問ptr2 所指向的儲存區時是不安全的。至於為什麼,讀者結合例十八來想一想,應該會明白的。

經過乙個系列的對指標的學習,現在你是否已經覺得指標再也不是你所想的那麼害怕了,如果你的回答是:對,我不怕了!哈哈,恭喜你,你已經掌握c 語言的精華了,c中唯一的難點就是指標,指標搞定其它小菜而已,重要的是實踐,好吧,讓我們先暫停c 的旅程吧,開始我們的c++程式設計,c 是對底層操作非常方便的語言,但開發大型程式本人覺得還是沒有c++方便,至少維護方面不太好做。而且c++是物件導向的語言,現在基本已經是物件導向的天下了,所以建議學c++。c++是一門難學易用的語言,要真正掌握c++可不是那麼容易的,將基本的學完後,就學資料結構吧,演算法才是永恆的,程式語言層出不窮,永遠學不完。

不要傷害指標(4) 指標和函式的關係

可以把乙個指標宣告成為乙個指向函式的指標.int fun1 char int int pfun1 char int pfun1 fun1 int a pfun1 abcdefg 7 通過函式指標呼叫函式。可以把指標作為函式的形參。在函式呼叫語句中,可以用指標表示式來作為實參。完全可以想象在記憶體的 ...

不要傷害指標(3) 指標和結構型別的關係

可以宣告乙個指向結構型別物件的指標。struct mystruct struct mystruct ss 宣告了結構物件ss,並把ss 的成員初始化為20,30 和40。struct mystruct ptr ss 宣告了乙個指向結構物件ss 的指標。它的型別是mystruct 它指向的型別是mys...

不要傷害指標(2) 指標的型別和指標所指向的型別

在談論指標之前,永遠記住指標的四要素 指標的型別,指標所指向的型別,指標指向的記憶體區,指標自身佔據的記憶體。指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。要搞清乙個指標需要搞清指標的四方面的內容 指標的型別 指標所指向的型別 指標的值或者叫指標所指向的記憶體區 指標本身所佔據...