Cprogramming 简明教程

Dangling Pointers in C

Dangling Pointers in C

C 中的 Dangling pointers 用于描述 pointer 当其目标(它指向的变量)已释放或不再可以访问时的行为。换句话说,C 中的 dangling pointer 是一个不指向适当类型的有效变量的指针。

Why Do We Get Dangling Pointers in C?

使用悬空指针在 C 程序中可能会导致不可预测的行为,有时还可能导致程序崩溃。悬空指针的情况可能由于以下原因而发生 −

  1. De-allocation of memory

  2. 访问越界内存位置

  3. 当变量超出范围时

让我们借助示例分析这三种情况中的每一种。

De-allocation of Memory

指针持有 variable 的地址。如果目标变量被释放,则其指针将成为悬空指针。尝试访问其目标变量已释放的指针会导致垃圾情况。

让我们使用 malloc() 创建一个整数变量并在整数指针中存储它的地址。

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

此处,指针引用内存中的一个有效位置。让我们使用 free() 函数释放 "x" 指向的内存。

free(x);

现在,“x”存储的是不再有效的地址。因此,如果我们尝试取消它的引用,编译器将显示某个垃圾值。

Example

以下示例展示了如何在 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

Accessing an Out-of-Bounds Memory Location

我们知道 function 可以返回指针。如果它返回函数内部任何局部变量的指针,它会导致外部范围中出现悬空指针,因为它所指向的位置不再有效。

Example

查看以下代码:

#include <stdio.h>

int * function();

int main(){

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

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

编译时,以下 warning 将显示在函数中的“return &a”语句中:

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

如果你在有警告的情况下运行程序,你将得到以下 error

Segmentation fault (core dumped)

当出现此错误时,这意味着程序正在尝试访问超出范围的内存位置。

When a Variable Goes Out of Scope

当在外部访问在内部块中声明的变量时也会出现相同的原因。在以下示例中,我们在块内有一个变量,且它的地址存储在指针变量中。

但是,在块外,指针变成悬空指针,因为它的目标超出范围。

Example

以下程序展示了当它的基本变量超出范围时如何得到悬空指针:

#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

How to Fix Dangling Pointers?

C 并没有自动垃圾回收功能,因此我们需要仔细管理动态分配的内存。

为了修复悬空指针问题或完全避免它们,你需要适用适当的内存管理,并尝试避免最终可能得到悬空指针的情况。

以下是你可以在避免悬空指针时遵循的一些 general guidelines

  1. * 在取消分配内存后,始终确保指针设置为 NULL。它将明确表明指针不再指向有效的内存位置。

  2. * 避免访问已经超出范围的变量或内存位置。

  3. * 不要返回局部变量的指针,因为此类局部变量在函数返回时将超出范围。

通过遵循这些指南,你可以在代码中减少得到悬空指针的可能性。