C語言的空類型指針,空指針,野指針詳解
空類型指針-void*
void是空類型,void*是空類型指針,又叫萬能指針,就是該指針能接收任意類型的指針,可以指向任何類型對象,所以不能對空類型指針進行解引用,必須強制類型轉換成相應的指針類型,才能進行解引用操作。
空指針類型:
- 作為函數(shù)形參類型,可以接收任意類型的指針;
- 作為函數(shù)返回值類型,在函數(shù)外面,將其強制類型轉換為相應的指針類型
- 可以與另一個void*類型指針比較大小
注意:空類型指針不能進行解引用操作;不能進行±整數(shù)運算。
空指針-NULL
在C語言中,空指針NULL指的是地址為0的那塊空間
#define NULL((void*)0)
對于這塊空間是不準我們進行訪問的,所以,對NULL是不能進行解引用操作的,所以每次對指針進行解引用操作之前,我們要判斷是否為空指針。
野指針
野指針是指向一個非法的或已銷毀的內存的指針。
對野指針進行解引用操作是非法的。
造成野指針的原因
1.指針未初始化
int main()
{
char* p;
//此時p是野指針
return 0;
}
沒有對指針p進行初始化,此時p就是野指針,如果此時對p進行解引用操作,非法訪問內存,程序就會崩潰。
2.指針越界訪問
int main()
{
int arr[] = {1,2,3,4,5};
int* p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ",p[i]);
}
return 0;
}
雖然上面程序正常運行,但是其實越界訪問了;只是僅僅訪問了非法的內存空間,沒有改變空間的值,程序有可能沒來得及報錯,但并不代表程序沒有錯,但是對于下面的代碼,程序就會崩潰:
int main()
{
int arr[10] = {0};
int i = 0;
int* p = arr;
for (i = 0; i <= 10; i++)
{
*p = i;
p++;
}
return 0;
}
因為這里非法訪問內存的同時試圖改變空間的值,所以程序崩潰。
3.指針指向的空間已經(jīng)釋放
char* fun()
{
char arr[] = "abc";
return arr;
}
int main()
{
char* p = fun();
printf("%s\n",p);
return 0;
}
執(zhí)行程序,給出如下警告

雖然程序沒有崩潰,但是這種寫法是非法的,arr是局部變量,函數(shù)調用結束,棧幀銷毀,局部變量空間歸還給操作系統(tǒng),我們沒有使用權限,此時p就是野指針,*p屬于非法訪問內存。
避免野指針
1.指針要進行初始化
指針要有初始值,初始化為NULL,或者有具體的指向。
既然NULL也不能進行解引用操作,那么為什么可以將指針初始化為NULL?這里初始化為NULL,只是為了給指針一個指向,但是實際使用時,我們并不能對NULL進行解引用操作,所以使用指針之前才要有效性判斷。
2.使用指針之前要進行有效性判斷
使用指針之前,要判斷是否為NULL,如果為NULL,那么是不能進行解引用操作的
3.避免越界訪問
不要進行越界訪問操作,即使還是訪問不改變值也是非法的
4.不要返回局部變量的地址
局部變量空間在函數(shù)到調用結束,就歸還給操作系統(tǒng),如果返回局部變量的地址,函數(shù)外面接收該返回值的指針就變成了野指針
5.當指針指向的空間釋放后,要將該指針置為NULL
這樣避免對野指針解引用操作,同時避免二次釋放動態(tài)開辟的內存空間
int main()
{
int* p = (int*)malloc(10*sizeof(int));
//1.判斷有效性
if (p == NULL)
{
return -1;
}
//2.使用指針
int i = 0;
for (i = 0; i < 10; i++)
{
p[i] = i;
}
//3.釋放指針指向的空間
free(p);
//free(p);//非法操作
//4.指針置為NULL
p = NULL;
free(p);//釋放空指針什么都不做
return 0;
}
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
解析C++中的虛擬函數(shù)及其靜態(tài)類型和動態(tài)類型
虛擬函數(shù)(Visual Function)亦常被成為虛函數(shù),是C++中的一個重要特性,本文我們就來解析C++中的虛擬函數(shù)及其靜態(tài)類型和動態(tài)類型2016-06-06

