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

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

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

野指針

定義

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

用途

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

原理

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

指針未初始化

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

int *ptr; // 聲明了一個指針變量ptr,但未初始化  
*ptr = 10; // 嘗試解引用ptr,這是未定義行為,因為ptr是野指針

指針越界訪問

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

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

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

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

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

返回局部變量的地址

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

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

指針運算錯誤

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

如何避免出現(xiàn)

初始化指針

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

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

檢查指針是否為NULL

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

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

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

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

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

避免返回局部變量的地址

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

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

// 范例之一:返回動態(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_ptrstd::shared_ptr等智能指針可以自動管理內(nèi)存的生命周期,從而減少野指針的風(fēng)險。

注意指針運算

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

代碼審查和測試

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

空指針

定義

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

用途

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

原理

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

舉例:

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論