“取消引用NULL指针”意味着什么?

时间:2010-10-24 05:07:18

标签: c pointers

我是C的完全新手,在我的大学工作期间,我遇到了代码中的注释,这些注释通常指的是取消引用NULL指针。我确实有C#的背景知识,我一直认为这可能类似于你在.Net中获得的“NullReferenceException”,但现在我有了严重的疑虑。

有人可以用非专业人士的语言向我解释这是什么以及它为什么不好?

6 个答案:

答案 0 :(得分:64)

NULL指针指向不存在的内存。这可以是地址0x00000000或任何其他实现定义的值(只要它永远不会是真实地址)。取消引用它意味着尝试访问指针指向的任何内容。 *运算符是解除引用运算符:

int a, b, c; // some integers
int *pi;     // a pointer to an integer

a = 5;
pi = &a; // pi points to a
b = *pi; // b is now 5
pi = NULL;
c = *pi; // this is a NULL pointer dereference

这与C#中的NullReferenceException完全相同,只是C中的指针可以指向任何数据对象,甚至是数组中的元素。

答案 1 :(得分:27)

解除引用只是意味着读取给定地址的内存值。因此,当你有一个指向某个东西的指针时,取消引用指针意味着读取或写入指针所指向的数据。

在C中,一元*运算符是解除引用运算符。如果x是指针,那么*x就是x指向的内容。一元&运算符是地址 - 运算符。如果x为任何内容,则&xx存储在内存中的地址。 *&运算符是彼此相反的:如果x是任何数据,而y是任何指针,则这些方程式始终为真:

*(&x) == x
&(*y) == y

空指针是一个不指向任何有效数据的指针(但它不是唯一的指针)。 C标准表示取消引用空指针是未定义的行为。这意味着绝对可能发生任何事情:程序可能会崩溃,它可能会继续无声地工作,或者它可能会擦除您的硬盘驱动器(尽管这不太可能)。

在大多数实现中,如果您尝试这样做,将会出现“分段错误”或“访问冲突”,这几乎总会导致您的程序被操作系统终止。这是空指针可以解除引用的一种方式:

int *x = NULL;  // x is a null pointer
int y = *x;     // CRASH: dereference x, trying to read it
*x = 0;         // CRASH: dereference x, trying to write it

是的,取消引用空指针几乎就像C#中的NullReferenceException(或Java中的NullPointerException),除了langauge标准在这里更有用。在C#中,取消引用空引用具有明确定义的行为:它始终抛出NullReferenceException。你的程序无法继续静默工作或者像C语言那样擦除硬盘驱动器(除非语言运行时出现错误,但同样非常不可能)。

答案 2 :(得分:2)

这意味着

myclass *p = NULL;
*p = ...;  // illegal: dereferencing NULL pointer
... = *p;  // illegal: dereferencing NULL pointer
p->meth(); // illegal: equivalent to (*p).meth(), which is dereferencing NULL pointer

myclass *p = /* some legal, non-NULL pointer */;
*p = ...;  // Ok
... = *p;  // Ok
p->meth(); // Ok, if myclass::meth() exists

基本上,几乎所有涉及(*p)或隐含涉及(*p)的内容,例如p->...这是(*p). ...的简写;除了指针声明。

答案 3 :(得分:0)

来自wiki

  

空指针具有保留值,通常但不一定是零值,表示它指的是没有对象
  ..

     

由于空值指针不引用有意义的对象,因此尝试取消引用空指针通常会导致运行时错误。

int val =1;
int *p = NULL;
*p = val; // Whooosh!!!! 

答案 4 :(得分:0)

引自wikipedia

  

指针引用了一个位置   记忆,并获得该值   指针所指的位置是已知的   as 解除引用指针。

通过在指针上应用unary *运算符来完成解除引用。

int x = 5;
int * p;      // pointer declaration
p = &x;       // pointer assignment
*p = 7;       // pointer dereferencing, example 1
int y = *p;   // pointer dereferencing, example 2

“取消引用NULL指针”表示*pp时执行NULL

答案 5 :(得分:0)

一个NULL指针指向不存在的内存,并且会引发 Segmentation错误。取消引用 NULL 指针有一种更简单的方法,看看。

int main(int argc, char const *argv[])
{
    *(int *)0 = 0; // Segmentation fault (core dumped)
    return 0;
}

由于 0 永远不是有效的指针值,所以会发生错误。

SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL}