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 ", *x); free (x); printf("x: %d ", *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' 现在超出了作用域 // ptr 现在是一个悬垂指针 printf("%d", ptr); return 0; }
输出
它将显示一个垃圾值 -
6422036
如何修复悬垂指针?
C 语言没有自动垃圾回收功能,因此我们需要谨慎管理动态分配的内存。
要修复悬垂指针问题或完全避免悬垂指针,您需要应用适当的内存管理,并尽量避免最终可能出现悬垂指针的情况。
以下是一些可以遵循的通用准则,以避免悬垂指针 -
- 始终确保在释放内存后将指针设置为 NULL。它将清楚地表明指针不再指向有效的内存位置。
- 避免访问超出范围的变量或内存位置。
- 不要返回指向局部变量的指针,因为此类局部变量在函数返回时将超出范围。
遵循这些准则,您可以减少代码中出现悬垂指针的可能性。