溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C語言空類型中指針和空指針以及野指針的作用是什么

發(fā)布時間:2021-09-24 17:32:01 來源:億速云 閱讀:415 作者:柒染 欄目:開發(fā)技術(shù)

C語言空類型中指針和空指針以及野指針的作用是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

    空類型指針-void*

    void是空類型,void*是空類型指針,又叫萬能指針,就是該指針能接收任意類型的指針,可以指向任何類型對象,所以不能對空類型指針進行解引用,必須強制類型轉(zhuǎn)換成相應(yīng)的指針類型,才能進行解引用操作。

    空指針類型:

    • 作為函數(shù)形參類型,可以接收任意類型的指針;

    • 作為函數(shù)返回值類型,在函數(shù)外面,將其強制類型轉(zhuǎn)換為相應(yīng)的指針類型

    • 可以與另一個void*類型指針比較大小

    注意:空類型指針不能進行解引用操作;不能進行±整數(shù)運算。

    空指針-NULL

    在C語言中,空指針NULL指的是地址為0的那塊空間

    #define NULL((void*)0)

    對于這塊空間是不準(zhǔn)我們進行訪問的,所以,對NULL是不能進行解引用操作的,所以每次對指針進行解引用操作之前,我們要判斷是否為空指針。

    野指針

    野指針是指向一個非法的或已銷毀的內(nèi)存的指針。

    對野指針進行解引用操作是非法的。

    造成野指針的原因

    1.指針未初始化
    int main()
    {
    	char* p;
    	//此時p是野指針
    	return 0;
    }

    沒有對指針p進行初始化,此時p就是野指針,如果此時對p進行解引用操作,非法訪問內(nèi)存,程序就會崩潰。

    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;
    }

    雖然上面程序正常運行,但是其實越界訪問了;只是僅僅訪問了非法的內(nèi)存空間,沒有改變空間的值,程序有可能沒來得及報錯,但并不代表程序沒有錯,但是對于下面的代碼,程序就會崩潰:

    int main()
    {
    	int arr[10] = {0};
    	int i = 0;
    	int* p = arr;
    
    	for (i = 0; i <= 10; i++)
    	{
    		*p = i;
    		p++;
    	}
    
    	return 0;
    }

    因為這里非法訪問內(nèi)存的同時試圖改變空間的值,所以程序崩潰。

    3.指針指向的空間已經(jīng)釋放
    char* fun()
    {
    	char arr[] = "abc";
    	return arr;
    }
    
    int main()
    {
    	char* p = fun();
    	printf("%s\n",p);
    	return 0;
    }

    執(zhí)行程序,給出如下警告

    C語言空類型中指針和空指針以及野指針的作用是什么

    雖然程序沒有崩潰,但是這種寫法是非法的,arr是局部變量,函數(shù)調(diào)用結(jié)束,棧幀銷毀,局部變量空間歸還給操作系統(tǒng),我們沒有使用權(quán)限,此時p就是野指針,*p屬于非法訪問內(nèi)存。

    避免野指針

    1.指針要進行初始化

    指針要有初始值,初始化為NULL,或者有具體的指向。

    既然NULL也不能進行解引用操作,那么為什么可以將指針初始化為NULL?這里初始化為NULL,只是為了給指針一個指向,但是實際使用時,我們并不能對NULL進行解引用操作,所以使用指針之前才要有效性判斷。

    2.使用指針之前要進行有效性判斷

    使用指針之前,要判斷是否為NULL,如果為NULL,那么是不能進行解引用操作的

    3.避免越界訪問

    不要進行越界訪問操作,即使還是訪問不改變值也是非法的

    4.不要返回局部變量的地址

    局部變量空間在函數(shù)到調(diào)用結(jié)束,就歸還給操作系統(tǒng),如果返回局部變量的地址,函數(shù)外面接收該返回值的指針就變成了野指針

    5.當(dāng)指針指向的空間釋放后,要將該指針置為NULL

    這樣避免對野指針解引用操作,同時避免二次釋放動態(tài)開辟的內(nè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;
    }

    看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI