1、懸空指針
C語言中的指針能夠指向一塊內存,若是這塊內存稍後被操做系統回收(被釋放),可是指針仍然指向這塊內存,那麼,此時該指針就是「懸空指針」。下面這段C語言代碼是一個例子,請看:
void *p = malloc(size);
assert(p);
free(p);
// 如今 p 是「懸空指針」
C語言中的「懸空指針」會引起不可預知的錯誤,並且這種錯誤一旦發生,很難定位。這是由於在 free(p) 以後,p 指針仍然指向以前分配的內存,若是這塊內存暫時能夠被程序訪問而且不會形成衝突,那麼以後使用 p 並不會引起錯誤。
因此在實際的C語言程序開發中,爲了不出現「懸空指針」引起不可預知的錯誤,在釋放內存以後,經常會將指針 p 賦值爲 NULL:
void *p = malloc(size);
assert(p);
free(p);
// 避免「懸空指針」
p = NULL;
這麼作的好處是一旦再次使用被釋放的指針 p,就會馬上引起「段錯誤」,程序員也就能馬上知道應該修改C語言代碼了。
2、野指針
上面咱們講的「懸空指針」是指向被釋放內存的指針,「野指針」則是不肯定其具體指向的指針。「野指針」最常來自於未初始化的指針,例以下面這段C語言代碼:
void *p;
// 此時 p 是「野指針」
由於「野指針」可能指向任意內存段,所以它可能會損壞正常的數據,也有可能引起其餘未知錯誤,因此C語言中的「野指針」危害性甚至比「懸空指針」還要嚴重。在實際的C語言程序開發中,定義指針時,通常都要儘可能避免「野指針」的出現(賦初值):
void *p = NULL;
void *data = malloc(size);