懸掛指針

懸掛指針

懸掛指針(又稱野指針)是計算機科學術語,指指向無效記憶體地址的指針,可能導致程式訪問非法記憶體或引發運行時錯誤,通常因記憶體管理不當形成。

其常見情形包括未初始化指針直接使用、指針所指對象生命周期結束(如局部變數被釋放)以及釋放記憶體後未置空指針。例如,指針指向已釋放的棧空間變數時,可能輸出隨機值。部分編譯器(如Visual Studio)會發出警告但不中斷程式運行。為規避風險,C語言建議將未使用指針初始化為NULL,釋放記憶體後立即置空,並謹慎處理realloc等函式。

隨著程式語言發展,C++引入引用機制替代部分指針場景,通過強制初始化減少懸掛指針風險。相關實踐方法逐步成為記憶體管理的基礎規範。

基本介紹

  • 中文名:懸掛指針
  • 外文名:Dangling Pointer
  • 領域:計算機編程
常見情形,避免方式,

常見情形

使用未初始化的指針
出現懸掛指針最典型的情形就是在定義指針變數之後沒有對它進行初始化,如下面的程式。
懸掛指針
懸掛指針

#include <iostream>
using namespace std;
 
int main(){
    int* p;
    cout<<*p<<endl; //編譯通過,運行時出錯
}
指針所指的對象已經消亡
指針指向某個對象之後,當這個對象的生命周期已經結束,對象已經消亡後,仍使用指針訪問該對象,將出現運行時錯誤。考察如下程式。
#include <iostream>
using namespace std;
 
int* retAddr(){
    int num=10;
    return #
}
 
int main(){
    int* p=NULL;
    p=retAddr();
    cout<<&p<<endl;
    cout<<*p<<endl;
}
以上程式編譯和運行都沒有錯誤,輸出結果如下:
最後一行,輸出的並非想像中的num的值10,因為變數num是存儲在棧空間的局部變數,離開函式超出其作用域後就會被釋放掉,因此輸出的值就是不確定的值了。
如果將cout<<&p<
VC++和g++都是這樣,
VS會在return #處發出警告
//warning C4172: 返回局部變數或臨時變數的地址: num
但並不會在運行時報錯。
指針釋放後之後未置空
指針p被free或者delete之後,沒有置為NULL,讓人誤以為p是個合法的指針。對指針進行free和delete,只是把指針所指的記憶體空間給釋放掉,但並沒有把指針本身置空,此時指針指向的就是“垃圾”記憶體。釋放後的指針應立即將指針置為NULL,防止產生懸掛指針。考察如下程式。
#include <iostream>
using namespace std;
 
int main(){
    int* p=NULL;
    p=new int[10];
    delete p;
    cout<<"p[0]:"<<p[0]<<endl;
}
程式輸出結果是一個隨機值,因為此時的指針所指向的空間是垃圾記憶體,存放著隨機值。
另在C語言中、realloc函式
1
2
3
4
5
6
7
8
9
#include
void main()
{
char*p,*q;
p=(char*)malloc(10);
q=p;
p=(char*)realloc(q,20);
//…………………………
}
在這段程式中我們用q記錄原來的記憶體地址p。這段程式可以編譯通過,但在執行到7行時,若原記憶體後面沒有足夠空間來將原有空間擴展成一個連續的新大小,那么realloc函式會從堆中重新找一塊30位元組大小的記憶體,並把原來(通過調用malloc函式得到的)記憶體空間中的內容複製到這塊新記憶體中,此時數據發生了移動,那么q所指向(通過調用malloc函式得到的)的記憶體空間實際上已經放回到堆上了!這樣就會產生q指針的指針懸掛,此時如果再用q指針進行操作就可能發生意想不到的問題。

避免方式

懸掛指針有時比較隱蔽,編譯器不能發現,為了防止懸掛指針帶來的危害,編程人員應該注意以下幾點。
(1)C++引入了引用機制,如果使用引用可以達到編程目的,就可以不必使用指針。因
為引用在定義的時候,必須初始化,所以可以避免懸掛指針的出現。
(2)如果一定要使用指針,那么需要在定義指針變數的同時對它進行初始化操作。定義時將其置位NULL或者指向一個有名變數。
(3)對指針進行free或者delete操作後,將其設定為NULL。對於使用 free 的情況,常常定義一個宏或者函式 xfree 來代替 free 置空指針:
#define xfree(x) free(x); x = NULL;
(4)在C語言中使用realloc函式時應當格外注意。

相關詞條

熱門詞條

聯絡我們