c中的野指针

与指针和内存管理有关的最常见的错误是悬空指针/野生指针。有时,程序员无法使用有效地址初始化指针,则这种类型的初始化指针在C语言中称为“悬空指针”。
当对象从内存中删除或取消分配而不修改指针的值时,在对象破坏时会发生悬挂指针。在这种情况下,指针指向已取消分配的内存。悬空指针可以指向内存,该内存包含程序代码或操作系统的代码。如果我们将值分配给该指针,则它将覆盖程序代码或操作系统指令的值;在这种情况下,程序将显示不良结果,甚至可能崩溃。如果将内存重新分配给某些其他进程,则我们取消引用悬空指针将导致分段错误。
让我们观察以下示例。

c中的野指针

文章图片
在上图中,我们可以看到Pointer 3是一个悬空的指针。指针1和指针2是分别指向所分配的对象,即对象1和对象2的指针。指针3是悬空指针,因为它指向已取消分配的对象。
让我们了解一些C程序的悬空指针。
使用free()函数取消分配内存。
#include < stdio.h> int main() { int *ptr=(int *)malloc(sizeof(int)); int a=560; ptr=&a; free(ptr); return 0; }

在上面的代码中,我们创建了两个变量,即* ptr和a,其中’ ptr’ 是指针,’ a’ 是整数变量。 * ptr是一个指针变量,它是通过malloc()函数创建的。我们知道malloc()函数返回void,因此我们使用int *将void指针转换为int指针。
语句int * ptr =(int *)malloc(sizeof(int)); 将为内存分配4个字节,如下图所示:
c中的野指针

文章图片
语句free(ptr)取消分配内存,如下图所示,带有叉号,并且’ ptr’ 指针指向已取消分配的内存时变得悬空。
c中的野指针

文章图片
如果我们将NULL值分配给’ ptr’ ,则’ ptr’ 将不会指向已删除的内存。因此,我们可以说ptr不是悬挂指针,如下图所示:
c中的野指针

文章图片
变量超出范围
当变量超出范围时,指向该变量的指针将变为悬空指针。
#include< stdio.h> int main() { char *str; { char a = ?A?; str = &a; } // a falls out of scope // str is now a dangling pointer printf("%s", *str); }

在上面的代码中,我们执行了以下步骤:
  • 首先,我们声明名为“ str”的指针变量。
  • 在内部范围内,我们声明一个字符变量。 str指针包含变量“ a”的地址。
  • 当控件超出内部范围时,“ a”变量将不再可用,因此str指向已取消分配的内存。这意味着str指针变成了悬空指针。
函数调用
现在,我们将看到调用函数时指针如何悬空。
让我们通过一个例子来理解。
#include < stdio.h> int *fun(){ int y=10; return &y; } int main() { int *p=fun(); printf("%d", *p); return 0; }

在上面的代码中,我们执行了以下步骤:
  • 首先,我们创建main()函数,在其中声明了“ p”指针,该指针包含fun()的返回值。
  • 调用fun()时,控件将移至int * fun()的上下文,fun()返回“ y”变量的地址。
  • 当控制权回到main()函数的上下文时,这意味着变量y不再可用。因此,我们可以说’ p’ 指针是一个悬空指针,因为它指向已取消分配的内存。
输出量
c中的野指针

文章图片
让我们以图形方式表示上述代码的工作。
c中的野指针

文章图片
让我们考虑另一个悬空指针的例子。
#include < stdio.h> int *fun() { static int y=10; return &y; } int main() { int *p=fun(); printf("%d", *p); return 0; }

上面的代码与前面的代码相似,但是唯一的区别是变量y是静态的。我们知道静态变量存储在全局存储器中。
输出量
c中的野指针

文章图片
现在,我们以图形方式表示上述代码的工作。
c中的野指针

文章图片
上图显示了堆栈存储器。首先,调用fun()函数,然后将控件移至int * fun()的上下文。由于“ y”是一个静态变量,因此它存储在全局内存中;它的范围在整个程序中都可用。当返回地址值时,控件将返回到main()的上下文。指针“ p”包含地址“ y”,即100。当我们打印“ * p”的值时,它将打印“ y”的值,即10。因此,我们可以说指针“ p”不是悬挂指针,因为它包含存储在全局存储器中的变量的地址。
避免悬空指针错误
【c中的野指针】通过将指针初始化为NULL值可以避免悬空的指针错误。如果我们将NULL值分配给指针,则指针将不会指向已取消分配的内存。为指针分配NULL值意味着该指针未指向任何内存位置。

    推荐阅读