失控指針

c\c++中,都有一個強大且具有極高危險性的東西:指針。若不恰當的使用指針,會造成很嚴重的後果。失控指針,也稱迷途指針/野指針/懸浮指針。是指將delete 用於指針(從而釋放它指向的記憶體),但沒有將它設定為空時引發。如果隨後你在沒有重新賦值的情況下使用該指針,後果將是不可預料的:計算機可能會崩潰!

基本介紹

  • 中文名:失控指針
  • 環境:c\c++
  • 別名迷途指針
  • 相關:空指針
說明,內部過程,空指針和失控指針,

說明

這個程式故意創建了一個失控指針:不要運行它,如果這樣做,有不同輸出算你走運,不幸運的話計算機可能會崩潰!
typedef unsigned short int USHORT;
#include <iostream>
int main ()
{
using namespace std;
USHORT *pInt = new USHORT ;
*pInt = 10 ;
cout << "pInt:" << *pInt << endl ;
delete pInt ;
long *pLong = new long ;
*pLong = 90000 ;
cout << "*pLong:" << *pLong << endl ;
*pInt = 20 ;
cout << "pInt:" << *pInt << endl ;
*pInt = 20 ;
cout << "*pInt:" << *pInt << endl ;
cout << "*pLong:" << *pLong << endl;
delete pLong ;
return 0 ;
}
輸出:
*pInt:10
*pLong:90000
*pInt:20
*pInt :65556
pInt聲明為一個USHORT指針,並將其指向使用new分配的記憶體,將10存儲到pInt指向的記憶體中,對指針使用delete後,pInt將成為一個失控指針。
接著聲明了一個新的指針pLong,它指向new分配的記憶體,將90000存儲到pLong指向的記憶體中。它指向的是pInt原來指向的記憶體塊,帶來麻煩的是 pInt = 20,它將20賦值到pInt原先指向的記憶體,(pInt被釋放後不再指向任何合法的記憶體,它仍可能指向原來的記憶體塊)將覆蓋pLong指向的記憶體。這被稱為重踏指針,它通常是使用失控指針產生的不幸後果。
總之。對指針使用delete後就不要再使用它。雖然這個指針仍指向原來的記憶體區域,但編譯器可能已經將其他數據存儲在這裡。不重新給這個指針複製就再次使用它可能導致程式崩潰;更糟糕的是,程式可能表面上運行正常但是過不了幾分鐘後就崩潰了。這被稱為定時炸彈,可不是好玩的。為了安全起見,刪除指針後,把其設定為空.這樣便解除了它的武裝。

內部過程

在上述程式中,pLong指向的記憶體中的值變為65556的過程如下:
(1)將pInt指向某個記憶體塊,並講10存儲到該記憶體塊。
(2)講delete用於指針pInt,這相當於告訴編譯器,可以將該記憶體塊用於存儲其他的東西,然後,指針pLong指向該記憶體塊。
(3)將90000賦給*pLong,在這個例子中使用的計算機按位元組交換順序存儲4位元組值90000(0015F90),因此它被存儲為5F900001。
(4)將20(十六進制為0014)賦給*pInt,由於pInt原來指向原來的地址,因此pLong的前兩個位元組被覆蓋,編程了00140001。
(5)列印*pLong的值,按位元組反轉為正確的順序00010014,然後被轉換為dos值65556。

空指針和失控指針

將delete用於指針時,實際是讓編譯器釋放記憶體,但指針本身仍然存在,它是一個失控指針。如果接下來為該指針賦值為0,它將成為一個空指針。
通常,如果對指針使用delete後再次對其使用delete,後果將是不確定的,也就是說,任何結果都有可能,幸運的話,僅僅是程式會崩潰。但對空指針使用delete,則任何事都沒有,這是很安全的做法。
使用失控指針或空指針是非法的,可能導致程式崩潰,如果是空指針,程式會崩潰,這是空指針相對於失控指針的一個優點,可預測的崩潰更可取,因為更容易調試

相關詞條

熱門詞條

聯絡我們