C語言中的懸空指標



C語言中的懸空指標

C語言中的**懸空指標**用於描述當一個指標的目標(它指向的變數)已被釋放或不再可訪問時,該指標的行為。換句話說,C語言中的**懸空指標**是指向無效變數(不屬於適當型別)的指標。

為什麼C語言中會出現懸空指標?

使用懸空指標可能會導致C程式出現不可預測的行為,有時甚至會導致程式崩潰。懸空指標的情況可能由於以下原因導致:

  • 記憶體釋放
  • 訪問越界記憶體位置
  • 當變數超出作用域時

讓我們透過示例分析這三種情況。

記憶體釋放

指標儲存變數的地址。如果目標變數被釋放,則其指標變成懸空指標。嘗試訪問其目標變數已被釋放的指標會導致垃圾值。

讓我們使用malloc()建立一個整數變數並將它的地址儲存在一個整數指標中。

int *x = (int *) malloc(sizeof(int));
*x = 100;

這裡,指標引用記憶體中的一個有效位置。讓我們使用free()函式釋放“x”指向的記憶體。

free(x);

現在,“x”儲存了一個不再有效的地址。因此,如果我們嘗試對其進行解引用,編譯器會顯示某個垃圾值。

示例

以下示例展示瞭如何在C程式中最終得到懸空指標:

#include <stdio.h>

int main(){

   int *x = (int *) malloc(sizeof(int));
   *x = 100;
   printf("x: %d\n", *x);

   free (x);
   printf("x: %d\n", *x);
}

輸出

執行程式碼並檢查其輸出:

x: 100
x: 11665744

訪問越界記憶體位置

我們知道函式可以返回一個指標。如果它返回指向函式內部任何區域性變數的指標,則會導致在外部作用域中出現懸空指標,因為其指向的位置不再有效。

示例

請檢視以下程式碼:

#include <stdio.h>

int * function();

int main(){

   int *x = function();
   printf("x: %d", *x);
   return 0;
}

int * function(){
   int a =100;
   return &a;
}

輸出

編譯時,在函式中的“return &a”語句處會顯示以下警告

warning: function returns address of local variable [-Wreturn-local-addr]

儘管有警告,但如果執行程式,則會得到以下錯誤

Segmentation fault (core dumped)

出現此錯誤時,表示程式正在嘗試訪問越界的記憶體位置。

當變數超出作用域時

當在內部塊中宣告的變數在外部被訪問時,也會出現同樣的原因。在以下示例中,我們在一個塊中有一個變數,其地址儲存在一個指標變數中。

但是,在塊外部,指標成為懸空指標,因為其目標超出範圍。

示例

以下程式演示了當其基變數超出作用域時如何得到懸空指標:

#include <stdio.h>

int main(){
   int *ptr;{
      int a = 10;
      ptr = &a;
   }

   // 'a' is now out of scope
   // ptr is a dangling pointer now
   printf("%d", ptr);

   return 0;
}

輸出

它將顯示一個垃圾值:

6422036

如何修復懸空指標?

C語言沒有自動垃圾回收功能,因此我們需要仔細管理動態分配的記憶體。

要修復懸空指標問題或完全避免它們,您需要應用正確的記憶體管理,並嘗試避免可能導致懸空指標的情況。

以下是一些可以遵循的一般準則,以避免懸空指標:

  • 始終確保在釋放記憶體後將指標設定為NULL。這將清楚地表明指標不再指向有效記憶體位置。
  • 避免訪問超出作用域的變數或記憶體位置。
  • 不要返回指向區域性變數的指標,因為此類區域性變數將在函式返回時超出作用域。

遵循這些準則,可以減少程式碼中出現懸空指標的可能性。

廣告