逍遙自在學C語言 | 指標陷阱-空指標與野指標

2023-06-26 06:00:59

前言

在C語言中,指標是一種非常強大和靈活的工具,但同時也容易引發一些問題,其中包括空指標和野指標。

本文將帶你瞭解這兩個概念的含義、產生原因以及如何避免它們所導致的問題。

一、人物簡介

  • 第一位閃亮登場,有請今後會一直教我們C語言的老師 —— 自在。

  • 第二位上場的是和我們一起學習的小白程式猿 —— 逍遙。

二、空指標

  • 空指標是指不指向任何有效記憶體地址的指標。

  • 在C語言中,可以用NULL宏來表示空指標。

  • 當一個指標被賦值為NULL時,它不指向任何有效的記憶體位置。

  • 下面是一個範例程式碼,演示瞭如何使用空指標:

#include <stdio.h>

int main() {
    int *ptr = NULL;  // 宣告一個指向整數的空指標

    if (ptr == NULL) {
        printf("指標為空。\n");
    } else {
        printf("指標不為空。\n");
    }

    return 0;
}

  • 輸出結果:
指標為空。
  • 在上述程式碼中,我們宣告了一個指向整數的空指標ptr,並將其賦值為NULL。

  • 然後,我們使用條件語句檢查指標是否為空,並列印相應的訊息。

三、野指標

  • 野指標是指指向未知、無效或已釋放的記憶體位置的指標。

  • 當一個指標被賦值為未初始化的值、已經釋放的記憶體地址,或者指向一個不再有效的物件時,它就成為了野指標。

  • 下面是一個範例程式碼,演示了野指標的行為:

#include <stdio.h>

int main() {
    int *ptr;  // 未初始化的指標

    *ptr = 42;  // 野指標的解除參照

    printf("野指標的值: %d\n", *ptr);

    return 0;
}

  • 輸出結果:
Segmentation fault
  • 在上述程式碼中,我們宣告了一個未初始化的指標ptr,然後嘗試對其進行解除參照並賦值。

  • 由於該指標沒有指向任何有效的記憶體地址,這將導致程式崩潰並引發段錯誤。

四、空指標和野指標的產生

空指標和野指標的產生主要源於以下幾種情況:

1、空指標的產生

  • 在宣告指標時將其初始化為NULL:當我們宣告一個指標但沒有為其分配有效的記憶體地址時,可以將其初始化為NULL,表示該指標不指向任何有效的記憶體位置。
  • 在釋放記憶體後未將指標置為NULL:當我們釋放了一個指標所指向的記憶體後,為了避免野指標的產生,應該將指標設定為NULL。否則,該指標將繼續指向已經釋放的記憶體位置,成為野指標。

2、 野指標的產生

  • 未初始化的指標:當我們宣告一個指標但未對其進行初始化時,該指標的值是未知的。
  • 已釋放的記憶體地址:當我們釋放了一塊記憶體後,如果仍然持有指向該記憶體地址的指標,並且對該指標進行解除參照操作,就會導致野指標的產生。
  • 指向超出作用域的區域性變數:當一個指標指向了超出其所在作用域的區域性變數時,當該指標被使用時就會產生野指標。這是因為當函數返回後,區域性變數的記憶體將不再有效,但指標仍然保持指向該記憶體地址。

五、 空指標和野指標導致的問題

空指標和野指標可能導致以下問題:

  • 程式崩潰:當野指標被解除參照時,存取無效的記憶體位置可能導致程式崩潰,並引發諸如段錯誤等的執行時錯誤。
  • 記憶體漏失:如果指標被設定為指向一塊已釋放的記憶體,這將導致記憶體漏失。記憶體漏失會消耗系統資源,並可能導致程式效能下降或崩潰。
  • 無法預測的行為:對空指標或野指標進行解除參照操作會導致不可預測的行為,因為存取的記憶體位置是未知的。

六、避免產生野指標的方法

  • 初始化指標變數:在宣告指標變數後,確保及時為其分配有效的記憶體地址。
  • 及時釋放記憶體並置空指標:在不再需要使用某個指標指向的記憶體時,及時釋放該記憶體,並將指標設定為NULL。
  • 避免越過作用域使用指標:確保指標不會超出其所在作用域範圍。當指標指向區域性變數時,確保在變數超出作用域前不再使用該指標。
  • 注意指標的生命週期:在使用指標時,瞭解指標所指向的物件的生命週期。確保指標只在物件有效的時間段內使用,並在物件失效後避免使用指標。

小結

通過這篇文章,我們學會了

1、空指標的概念

2、野指標的概念

3、空指標和野指標的產生

4、空指標和野指標導致的問題,避免野指標產生的方法。