欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言實(shí)現(xiàn)野指針的示例代碼

 更新時(shí)間:2024年11月26日 08:48:55   作者:米飯「」  
本文詳細(xì)介紹了野指針的概念、產(chǎn)生原因及規(guī)避方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、野指針

1.野指針的概念

指向位置是不可知的、隨機(jī)的、不正確的、沒(méi)有明確限制的指針就叫野指針。

2.產(chǎn)生原因

野指針產(chǎn)生的原因有:
(1) 指針未初始化
創(chuàng)建指針變量時(shí)未對(duì)其進(jìn)行初始化賦值,則這個(gè)指針指向的位置是隨機(jī)的。

#include<stdio.h>
int main()
{
	int* p;//局部變量指針未初始化,默認(rèn)為隨機(jī)值
	return 0;
}

(2) 指針指向的空間被釋放
①如果一個(gè)(局部)變量出了作用域或者是這個(gè)變量的生命周期結(jié)束了,那變量就會(huì)被銷(xiāo)毀,變量所占的內(nèi)存會(huì)還給操作系統(tǒng),此時(shí)如果還使用指針訪問(wèn)該變量,那就會(huì)出現(xiàn)野指針,編譯器就會(huì)報(bào)錯(cuò)了。

#include<stdio.h>
int* test()
{
	int n = 10;
	return &n;
}
int main()
{
	int* p = test();
	printf("%d\n", *p);
	return 0;
}

②指針被free之后,沒(méi)有被置為NULL。對(duì)指針進(jìn)行free只是把指針?biāo)赶虻目臻g釋放掉,但并沒(méi)有把指針本身置為空,此時(shí)指針指向的就是垃圾內(nèi)存,所以釋放后的指針應(yīng)該立即置為NULL,養(yǎng)成良好的編程習(xí)慣,以防產(chǎn)生野指針。

在這里插入圖片描述

(3) 指針越界訪問(wèn)
在使用指針訪問(wèn)數(shù)組元素時(shí),超出數(shù)組的范圍,就會(huì)造成非法訪問(wèn),因?yàn)槟菈K空間不屬于數(shù)組的范圍,就會(huì)出現(xiàn)野指針:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int* p = &arr[0];
	int i = 0;
	for (i = 0; i <= 10; i++)
    {
		//當(dāng)指針指向的范圍超出了數(shù)組arr的范圍時(shí),p就是野指針 
		*(p++) = i;
	}
	return 0;
}

3.如何規(guī)避野指針

(1) 指針初始化如果明確知道指針指向哪里就直接賦值地址,如果不知道指針應(yīng)該指向哪里,可以給指針賦值NULL。
NULL是C語(yǔ)言中定義的一個(gè)標(biāo)識(shí)符常量,值是0,0也是地址,這個(gè)地址是無(wú)法使用的,讀寫(xiě)該地址會(huì)報(bào)錯(cuò)。
正確使用指針示例:

#include<stdio.h>
int main()
{
	int num = 10;
	int* p1 = &num;
	int* p2 = NULL;
	return 0;
}

(2) 注意指針越界一個(gè)程序向內(nèi)存申請(qǐng)了哪些空間,通過(guò)指針也就只能訪問(wèn)哪些空間,不能超出范圍訪問(wèn),超出了就是越界訪問(wèn)。
(3) 指針變量不再使用時(shí),及時(shí)置為NULL,指針使用之前檢查其有效性當(dāng)指針變量指向一塊區(qū)域的時(shí)候,我們可以通過(guò)指針訪問(wèn)該區(qū)域,后期不再使用這個(gè)指針訪問(wèn)空間的時(shí)候,我們可以把該指針置為NULL。因?yàn)榧s定俗成的一個(gè)規(guī)則就是∶只要是NULL指針就不去訪問(wèn),同時(shí)使用指針之前可以判斷指針是否為NULL。
(4) 避免返回局部變量的地址通過(guò)上面的例子就可知道,局部變量一旦離開(kāi)了作用域,就會(huì)被銷(xiāo)毀,空間被釋放,此時(shí)不能再使用這塊空間的指針來(lái)訪問(wèn)此空間。

二、assert斷言函數(shù)

assert() 斷言函數(shù),用于在程序運(yùn)行過(guò)程中捕捉程序的錯(cuò)誤。在大部分編譯器下,assert()是一個(gè)宏;在少數(shù)編譯器下,assert就是一個(gè)函數(shù)。
assert() 函數(shù)在程序運(yùn)行時(shí)會(huì)對(duì)某種假設(shè)條件進(jìn)行檢測(cè),如果條件成立,程序就繼續(xù)往下執(zhí)行,如果條件不成立就會(huì)捕捉到這種錯(cuò)誤,并打印出錯(cuò)誤信息,終止程序運(yùn)行。assert()函數(shù)包含在assert.h這個(gè)頭文件中,assert翻譯過(guò)來(lái)的意思就是“斷言”。所以可以使用assert來(lái)判斷指針是否為NULL:

assert(p != NULL);

上面的代碼,在程序運(yùn)行到這一行語(yǔ)句時(shí),驗(yàn)證變量p是否等于NULL。如果確實(shí)不等于NULL,程序繼續(xù)運(yùn)行,否則就會(huì)終止運(yùn)行,并且給出報(bào)錯(cuò)信息:

#include<stdio.h>
#include<assert.h>
int main()
{
	int* p = NULL;
	assert(p != NULL);
	return 0;
}

運(yùn)行結(jié)果:

在這里插入圖片描述

由上圖,assert() 接收一個(gè)表達(dá)式作為參數(shù)。如果該表達(dá)式為真(非零),assert()不會(huì)產(chǎn)生任何作用,程序繼續(xù)運(yùn)行。如果該表達(dá)式為假(零),assert()就會(huì)報(bào)錯(cuò),在標(biāo)準(zhǔn)錯(cuò)誤流stderr中寫(xiě)入一條錯(cuò)誤信息,之后顯示沒(méi)有通過(guò)的表達(dá)式,以及包含這個(gè)表達(dá)式的文件名行號(hào)。關(guān)于的概念,后面會(huì)學(xué)習(xí)。

使用 assert() 的好處:
assert() 不僅能自動(dòng)標(biāo)識(shí)文件和出問(wèn)題的行號(hào),而且它還具備一種無(wú)需更改代碼就能開(kāi)啟或關(guān)閉的機(jī)制:如果已經(jīng)確認(rèn)程序沒(méi)有問(wèn)題,不需要再做斷言,就在 #include <assert.h> 語(yǔ)句的前面,定義一個(gè)宏NDEBUG,它的意思是No Debug(一旦定義了宏NDEBUG,assert() 就會(huì)失效):

#define NDEBUG
#include <assert.h>

然后,重新編譯程序,編譯器就會(huì)禁用文件中所有的 assert() 語(yǔ)句。如果程序又出現(xiàn)問(wèn)題,可以移除這條 #define NDEBUG 指令(或者把它注釋掉),再次編譯,這樣就重新啟用了 assert() 語(yǔ)句。

assert() 的缺點(diǎn):
assert() 的缺點(diǎn)是:因?yàn)橐肓祟~外的檢查,增加了程序的運(yùn)行時(shí)間。
一般我們?cè)贒ebug調(diào)試版本中使用assert,而在Release發(fā)行版本中選擇禁用assert。在VS這樣的集成開(kāi)發(fā)環(huán)境中,在Release版本中,assert直接就被優(yōu)化掉了。這樣在Debug版本中使用assert有利于程序員排查問(wèn)題,而在Release版本中不影響用戶使用程序時(shí)的效率。

到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)野指針的示例代碼的文章就介紹到這了,更多相關(guān)C語(yǔ)言 野指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt實(shí)現(xiàn)高精度定時(shí)器

    Qt實(shí)現(xiàn)高精度定時(shí)器

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)高精度定時(shí)器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語(yǔ)言指針詳解之野指針

    C語(yǔ)言指針詳解之野指針

    這篇文章主要為大家介紹了C語(yǔ)言野指針,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程詳解

    Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程詳解

    UDP 是User Datagram Protocol 的簡(jiǎn)稱,中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是一種無(wú)連接、不可靠的協(xié)議,本文主要介紹了如何在Linux下使用C/C++進(jìn)行UDP網(wǎng)絡(luò)編程,有需要的可以了解下
    2024-10-10
  • C++連連看判定圖形消除算法

    C++連連看判定圖形消除算法

    這篇文章主要為大家詳細(xì)介紹了C++連連看判定圖形消除算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 深入探討POJ 2312 Battle City 優(yōu)先隊(duì)列+BFS

    深入探討POJ 2312 Battle City 優(yōu)先隊(duì)列+BFS

    本篇文章是對(duì)優(yōu)先隊(duì)列+BFS進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解QML?調(diào)用?C++?中的內(nèi)容

    詳解QML?調(diào)用?C++?中的內(nèi)容

    這篇文章主要介紹了QML?怎么調(diào)用?C++?中的內(nèi)容,這里主要是總結(jié)一下,怎么在 QML 文件中引用 C ++ 文件里定義的內(nèi)容,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • C語(yǔ)言指針必備基礎(chǔ)全面覆蓋

    C語(yǔ)言指針必備基礎(chǔ)全面覆蓋

    數(shù)據(jù)對(duì)象是指存儲(chǔ)在內(nèi)存中的一個(gè)指定數(shù)據(jù)類(lèi)型的數(shù)值或字符串,它們都有一個(gè)自己的地址,指針是保存這個(gè)地址的變量,本篇文章帶你掌握C語(yǔ)言指針的用法
    2021-10-10
  • 深入解析C++中的mutable關(guān)鍵字

    深入解析C++中的mutable關(guān)鍵字

    在C++中,mutable也是為了突破const的限制而設(shè)置的。被mutable修飾的變量,將永遠(yuǎn)處于可變的狀態(tài),即使在一個(gè)const函數(shù)中
    2013-10-10
  • C語(yǔ)言中堆空間的生成與釋放詳解

    C語(yǔ)言中堆空間的生成與釋放詳解

    以下是對(duì)C語(yǔ)言中堆空間的生成與釋放進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • Qt實(shí)現(xiàn)部件透明陰影效果與不規(guī)則窗體詳解

    Qt實(shí)現(xiàn)部件透明陰影效果與不規(guī)則窗體詳解

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)部件透明陰影效果與不規(guī)則窗體的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-01-01

最新評(píng)論