在C语言中,“野指针”的含义是什么?

25

请问,在C语言中,什么是野指针?如何获得它?在C++中是否有这种情况?


13
野指针喜欢破坏程序。 - Tom
那不是狂野,而是愤怒的... - AnthonyLambert
一个仍然在三个月后随意戳来戳去,而没有人能让它安静下来的程序。 - Windows programmer
11个回答

53
标准并未定义或使用术语“wild”,我会谨慎地“纠正”他人关于其含义的观点,尤其是避免引用随意非规范互联网垃圾来支持我的立场。
对我而言,“wild”指的是既不指向合法对象也不是NULL的指针。这些类型的指针值可能来自未初始化的指针对象、已经停止存在的对象、计算得出的指针值、不正确对齐的指针值、指针本身或指向的内容被意外破坏等情况。
int main(void)
{

   int *p;  // uninitialized and non-static;  value undefined
   { 
      int i1; 
      p = &i1;  // valid 
   }            // i1 no longer exists;  p now invalid    

   p = (int*)0xABCDEF01;  // very likely not the address of a real object

   { 
      int i2;  
      p = (int*)(((char*)&i2) + 1);  // p very likely to not be aligned for int access
   }

   {
      char *oops = (char*)&p;  
      oops[0] = 'f';  oops[1] = 35;  // p was clobbered
   }
}  

等等,诸如此类的东西。在C语言中有各种各样的方法可以得到一个无效的指针值。我最喜欢的方式是有个人试图通过将它们的地址写入文件来“保存”他的对象。奇怪的是,在程序的不同运行期间,当他读回这些指针值时,它们不再指向他的对象了。很奇妙吧。

但对我来说,“wild”只是个形容词。由于它不是一个规范的术语,它意味着说话或写作者想要表达的任何含义。问问他或她就知道了。


11
感谢指出该术语不够精确,并提供了4个可能的原因。+1 - Steve Fallows

12

C语言中的野指针是指在第一次使用之前未被初始化的指针。

来自维基百科

通过省略必要的初始化而创建野指针。因此,严格地说,在不强制执行初始化的编程语言中,每个指针都开始作为野指针。

这通常是由于跳过初始化而发生的,而不是省略它。大多数编译器都能够警告这种情况。

例如:

int f(int i)
{
    char* dp;    //dp is a wild pointer
    ...
}

2
这个术语也用于指一个曾经被初始化过,但现在已经变成了野指针的指针。请参考Naveen的回答:https://dev59.com/4nE85IYBdhLWcg3w2HRa - sbi
1
@Magnus - 感谢您的编辑!@sbi - 我通常听到您描述的状态中指针被称为“悬空指针”,但是您正确地指出它们实际上处于与“野指针”相同的状态。 - Amal Sirisena
在许多具有动态内存的系统中,一个悬空指针所指向的数据在被重用之前似乎是有效的,而野指针则会指向垃圾。因此它们并不完全相同。 - Pete Kirkham

5

我会尽力帮助你进行翻译。以下是需要翻译的内容:

这不是一个标准术语。通常用于指向无效内存位置的指针。

int *p; *p = 0; //P是一个野指针

或者

int *p = NULL;
{
  int a;
  p = &a; // as soon as 'a' goes out of scope,'p' is pointing to invalid location
}

*p = 0;

3
当指针所指向的位置超出其作用域范围(或被释放)时,它就会成为悬空指针,而不是野指针。野指针是未初始化的指针。 - Technowise
1
@Technowise:我不同意。我听说这两个术语可以互换使用。 - sbi

3

获取一个野指针(也称为悬挂指针)的方法:

  • 创建一个对象
  • 创建指向该对象的指针
  • 删除该对象
  • 忘记将指针设置为 null

此时指针被称为“野指针”,因为它指向一个随意的内存空间,在此状态下使用它可能会导致程序出现问题。


1
我认为你应该称它们为“悬空指针”,而野指针则是未初始化的指针。 - Eineki
1
我猜挂钩指针不是野指针,尽管Eineiki这样说过。 - Frank Shearar
1
标准没有定义“wild”或“dangling”,因此这些更正充其量都是可疑的。标准使用术语“有效”和“无效”。 - janks
@sbi:仅在块作用域(即自动存储期)中才能这样定义。如果将其放在文件作用域,则需要将其初始化为NULL。 - janks

2

未初始化任何地址的指针被称为野指针。它可能包含任何垃圾地址,因此解引用野指针是危险的。


2

野指针是指任何在值不正确或不再正确的情况下使用的指针(特别是作为L_value {即(*pointer) = x})。它也可以用于描述将未定义为指针的内存用作指针(可能是通过跟随野指针或使用过时的结构定义)。

没有官方定义。这只是我们在引用某些指针错误或这些错误的结果时使用的词语。


1

维基百科

这是一个指向未初始化对象或状态不良的对象的指针。使用此指针会引起麻烦。维基百科是一个很好的解释来源。


如果一个对象违反了其不变量,也可以说它处于一个糟糕的状态,但指向它的指针并不是野指针。因此,该定义有些错误。 - sbi
这取决于错误状态的本质。但我理解你的观点,我已经参考了维基页面以获取确切的定义。 - Dani
请注意,该语言要求通过 unsigned char 类型的 lvalue 访问始终可以用于读取或写入对象,即使在将其解释为其声明类型时处于错误状态。 - janks

1

野指针是指向无效对象(如果适用,则为指定类型的对象)或区分的空值(如果适用)的指针。

在此处阅读有关野指针的更多信息


0

野指针是一个声明存在但尚未定义的指针。这意味着我们已经声明了一个指针 - data_type *ptr; // 但没有定义它所包含的地址 *ptr = 100 // 野指针不指向任何有效地址,因此我们会得到错误 printf("ptr:%d", ptr); // 在gcc编译器中,我们将得到:0


-1
一个没有指向任何数据类型变量的指针被称为野指针。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接