亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C語(yǔ)言中野指針和空指針的區(qū)別

 更新時(shí)間:2024年11月26日 09:06:47   作者:AzurSatr  
本文主要介紹了野指針和空指針的概念、用途、原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

野指針

定義

野指針是指那些指向了未知、隨機(jī)、不正確或已經(jīng)被釋放的內(nèi)存地址的指針變量。它們可能指向了程序棧上的某個(gè)臨時(shí)變量(該變量可能已經(jīng)出棧并被覆蓋),或者指向了已經(jīng)被freedelete釋放的內(nèi)存塊,或者根本就是一個(gè)隨機(jī)的、未初始化的內(nèi)存地址。
注:野指針不會(huì)直接引發(fā)錯(cuò)誤,操作野指針指向的內(nèi)存區(qū)域才會(huì)出問(wèn)題。

用途

(實(shí)際上,野指針應(yīng)該被避免):
野指針通常是由于編程錯(cuò)誤造成的,比如忘記初始化指針、釋放內(nèi)存后未將指針置為NULL等。由于它們指向的內(nèi)存狀態(tài)是不確定的,因此使用野指針往往會(huì)導(dǎo)致程序崩潰、數(shù)據(jù)損壞等嚴(yán)重問(wèn)題。

原理

野指針的產(chǎn)生往往與內(nèi)存管理不當(dāng)有關(guān)。在C語(yǔ)言中,需要手動(dòng)管理內(nèi)存(包括分配和釋放),如果在這個(gè)過(guò)程中出現(xiàn)了疏忽,就可能導(dǎo)致野指針的產(chǎn)生。

指針未初始化

在C語(yǔ)言中,指針變量在聲明時(shí)不會(huì)自動(dòng)初始化為NULL或任何其他值。如果在聲明指針后沒(méi)有立即為其分配一個(gè)有效的內(nèi)存地址或顯式地將其初始化為NULL,那么這個(gè)指針就會(huì)包含一個(gè)隨機(jī)的內(nèi)存地址,成為野指針。

int *ptr; // 聲明了一個(gè)指針變量ptr,但未初始化  
*ptr = 10; // 嘗試解引用ptr,這是未定義行為,因?yàn)閜tr是野指針

指針越界訪問(wèn)

當(dāng)指針被用來(lái)訪問(wèn)數(shù)組或其他連續(xù)內(nèi)存區(qū)域時(shí),如果訪問(wèn)的索引超出了其有效范圍,那么指針就會(huì)指向一個(gè)未知的內(nèi)存地址,從而成為野指針。

int arr[10];  
int *ptr = arr;  
for (int i = 0; i <= 12; i++) { // 注意循環(huán)條件,i會(huì)超出數(shù)組范圍  
    *(ptr + i) = i; // 當(dāng)i=10和i=11時(shí),ptr+i成為野指針  
}

釋放內(nèi)存后未置NULL

使用freedelete等函數(shù)釋放了指針?biāo)赶虻膬?nèi)存后,如果沒(méi)有將指針置為NULL,那么這個(gè)指針仍然會(huì)保留原來(lái)的內(nèi)存地址。此時(shí),如果程序繼續(xù)嘗試通過(guò)該指針訪問(wèn)內(nèi)存(盡管內(nèi)存可能已經(jīng)被系統(tǒng)重新分配給其他變量),就會(huì)導(dǎo)致未定義行為,因?yàn)樵撝羔樢呀?jīng)成為了野指針。

int *ptr = (int*)malloc(sizeof(int));  
if (ptr != NULL) {  
    *ptr = 10;  
    free(ptr); // 釋放內(nèi)存  
    // 忘記將ptr置為NULL  
    // ...  
    // 如果之后再次使用ptr,如*ptr = 20; 則ptr是野指針  
}

返回局部變量的地址

在函數(shù)中,如果返回了一個(gè)指向局部變量的指針,那么在函數(shù)返回后,局部變量會(huì)被銷(xiāo)毀,但返回的指針仍然指向那個(gè)已經(jīng)被銷(xiāo)毀的內(nèi)存地址。此時(shí),該指針就成為了野指針。

int* getPointer() {  
    int local = 10;  
    return &local; // 返回指向局部變量的指針  
}  
  
int main() {  
    int *ptr = getPointer(); // ptr成為野指針,因?yàn)閘ocal已經(jīng)被銷(xiāo)毀  
    // ...  
}

指針運(yùn)算錯(cuò)誤

在進(jìn)行指針運(yùn)算時(shí)(如指針加法、減法或遞增、遞減),如果運(yùn)算結(jié)果超出了合法內(nèi)存范圍,那么指針就會(huì)指向一個(gè)未知的內(nèi)存地址,從而成為野指針。

如何避免出現(xiàn)

初始化指針

在聲明指針變量時(shí),應(yīng)立即將其初始化為NULL或指向一個(gè)有效的內(nèi)存地址。這可以防止指針在未經(jīng)初始化的情況下就被使用,從而避免野指針的產(chǎn)生。指針變量剛被創(chuàng)建時(shí)不會(huì)自動(dòng)成為NULL指針,它的缺省值是隨機(jī)的,它所指的空間是隨機(jī)的。

int *ptr = NULL; // 初始化為NULL  
int array[10];  
int *arrayPtr = array; // 指向有效數(shù)組的首地址

檢查指針是否為NULL

在解引用指針之前,應(yīng)始終檢查它是否為NULL。這可以確保只有在指針指向有效內(nèi)存地址時(shí)才進(jìn)行解引用操作。

if (ptr != NULL) {  
    *ptr = 10; // 只有當(dāng)ptr不是NULL時(shí)才解引用  
}

釋放內(nèi)存后置NULL

在釋放指針?biāo)赶虻膬?nèi)存后,應(yīng)立即將指針置為NULL。這可以防止在之后的代碼中錯(cuò)誤地嘗試再次解引用該指針。

free(ptr);  
ptr = NULL; // 避免成為野指針

避免返回局部變量的地址

函數(shù)內(nèi)部定義的局部變量在函數(shù)返回時(shí)會(huì)被銷(xiāo)毀,因此不應(yīng)該返回指向這些局部變量的指針。如果需要返回?cái)?shù)據(jù),可以考慮返回?cái)?shù)據(jù)的副本、使用動(dòng)態(tài)分配的內(nèi)存、或者通過(guò)參數(shù)傳遞指針并在函數(shù)外部分配內(nèi)存。

// 反例 
int* badFunction() {  
    int local = 10;  
    return &local; // 返回指向局部變量的指針,可能導(dǎo)致野指針  
}  

// 范例之一:返回動(dòng)態(tài)分配的內(nèi)存  
int* goodFunction() {  
    int *ptr = (int*)malloc(sizeof(int));  
    if (ptr != NULL) {  
        *ptr = 10;  
    }  
    return ptr; // 注意:調(diào)用者需要負(fù)責(zé)釋放內(nèi)存  
}

使用智能指針(僅限C++)

使用std::unique_ptr、std::shared_ptr等智能指針可以自動(dòng)管理內(nèi)存的生命周期,從而減少野指針的風(fēng)險(xiǎn)。

注意指針運(yùn)算

在進(jìn)行指針運(yùn)算時(shí)(如遞增、遞減、加法、減法),要確保指針始終在合法范圍內(nèi)。避免指針越界訪問(wèn),這可能會(huì)導(dǎo)致野指針的出現(xiàn)(雖然不是直接的野指針,但可能導(dǎo)致不可預(yù)測(cè)的行為)。

代碼審查和測(cè)試

使用靜態(tài)分析工具、內(nèi)存泄漏檢測(cè)器和單元測(cè)試等工具。

空指針

定義

空指針是一個(gè)特殊的指針值,它不指向任何有效的內(nèi)存地址。在C語(yǔ)言中,空指針通常用宏NULL來(lái)表示,實(shí)際上NULL通常被定義為((void*)0)或簡(jiǎn)單地0。

用途

空指針主要用于表示指針當(dāng)前不指向任何對(duì)象。在初始化指針時(shí),將其設(shè)置為NULL可以明確地表明該指針當(dāng)前不指向任何有效內(nèi)存地址。此外,在釋放指針?biāo)赶虻膬?nèi)存后,將指針置為NULL可以防止野指針的產(chǎn)生。

原理

空指針的原理很簡(jiǎn)單,它就是一個(gè)特殊的值(通常是0),用于表示指針不指向任何內(nèi)存地址。在C語(yǔ)言中,任何嘗試解引用空指針的行為都是未定義的,通常會(huì)導(dǎo)致程序崩潰。

舉例:

#include <stdio.h>  
  
int main() {  
    int *ptr = NULL; // 聲明了一個(gè)指針變量ptr,并將其初始化為NULL,表示它不指向任何內(nèi)存地址  
  
    if (ptr != NULL) {  
        // 如果ptr不是NULL,則執(zhí)行這里的代碼(但在這個(gè)例子中,這里的代碼不會(huì)被執(zhí)行)  
    } else {  
        printf("ptr is NULL\n"); // 輸出ptr是空指針的信息  
    }  
  
    // 嘗試解引用ptr(這是不安全的,因?yàn)閜tr是NULL)  
    // *ptr = 10; // 這將導(dǎo)致未定義行為,因?yàn)閜tr是空指針  
  
    return 0;  
}

在上面的例子中,ptr被初始化為NULL,表示它不指向任何內(nèi)存地址。然后,我們通過(guò)if語(yǔ)句檢查ptr是否為NULL,并根據(jù)結(jié)果打印相應(yīng)的信息。注意,我們并沒(méi)有嘗試解引用ptr,因?yàn)檫@是一個(gè)空指針,解引用它是不安全的。

到此這篇關(guān)于C語(yǔ)言中野指針和空指針的區(qū)別的文章就介紹到這了,更多相關(guān)C語(yǔ)言 野指針和空指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Opencv實(shí)現(xiàn)輪廓提取功能

    Opencv實(shí)現(xiàn)輪廓提取功能

    這篇文章主要為大家詳細(xì)介紹了Opencv實(shí)現(xiàn)輪廓提取功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • VS2022永久配置OpenCV開(kāi)發(fā)環(huán)境的實(shí)現(xiàn)

    VS2022永久配置OpenCV開(kāi)發(fā)環(huán)境的實(shí)現(xiàn)

    本文主要介紹了VS2022永久配置OpenCV開(kāi)發(fā)環(huán)境的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++代碼改造為UTF-8編碼問(wèn)題的總結(jié)(最新推薦)

    C++代碼改造為UTF-8編碼問(wèn)題的總結(jié)(最新推薦)

    本文總結(jié)了如何將C++程序代碼改造為UTF-8編碼,包括操作系統(tǒng)、編譯器和終端等各方面的設(shè)置,在實(shí)際操作中,可以通過(guò)漸進(jìn)式更新的方式,只在新的代碼項(xiàng)目中使用UTF-8編碼,避免大規(guī)模修改舊代碼,感興趣的朋友一起看看吧
    2025-02-02
  • C/C++經(jīng)典算法之約瑟夫問(wèn)題詳解

    C/C++經(jīng)典算法之約瑟夫問(wèn)題詳解

    這篇文章主要給大家介紹了關(guān)于C/C++經(jīng)典算法之約瑟夫問(wèn)題的相關(guān)資料,約瑟夫環(huán)問(wèn)題是一道經(jīng)典的數(shù)據(jù)結(jié)構(gòu)的題目,本文介紹了解決約瑟夫問(wèn)題的三種方法,需要的朋友可以參考下
    2021-07-07
  • DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)與定點(diǎn)概述

    DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)與定點(diǎn)概述

    本文主要介紹DSP中浮點(diǎn)與定點(diǎn)概述,很值得學(xué)習(xí)一下,需要的朋友可以參考一下。
    2016-06-06
  • C語(yǔ)言深入分析數(shù)組指針和指針數(shù)組的應(yīng)用

    C語(yǔ)言深入分析數(shù)組指針和指針數(shù)組的應(yīng)用

    在C語(yǔ)言和C++等語(yǔ)言中,數(shù)組元素全為指針變量的數(shù)組稱(chēng)為指針數(shù)組,指針數(shù)組中的元素都必須具有相同的存儲(chǔ)類(lèi)型、指向相同數(shù)據(jù)類(lèi)型的指針變量。指針數(shù)組比較適合用來(lái)指向若干個(gè)字符串,使字符串處理更加方便、靈活
    2022-04-04
  • C++使用string的大數(shù)取模運(yùn)算(5)

    C++使用string的大數(shù)取模運(yùn)算(5)

    這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)取模運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 實(shí)例詳解C/C++中extern關(guān)鍵字

    實(shí)例詳解C/C++中extern關(guān)鍵字

    這篇文章主要介紹了C/C++中extern關(guān)鍵字詳解 的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • C++ 頭文件系列(set)詳解

    C++ 頭文件系列(set)詳解

    一般而言,每個(gè)C++/C程序通常由頭文件和定義文件組成。頭文件作為一種包含功能函數(shù)、數(shù)據(jù)接口聲明的載體文件,主要用于保存程序的聲明,而定義文件用于保存程序的實(shí)現(xiàn) 。
    2017-02-02
  • QT輸入框輸入限制整理(正則表達(dá)式限制)

    QT輸入框輸入限制整理(正則表達(dá)式限制)

    我們有時(shí)需要限制文本框輸入內(nèi)容的類(lèi)型,下面這篇文章主要給大家介紹了關(guān)于QT輸入框輸入限制的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-04-04

最新評(píng)論