C语言 “取消引用空指针”究竟是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4007268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:47:09  来源:igfitidea点击:

What EXACTLY is meant by "de-referencing a NULL pointer"?

cpointers

提问by Ash

I am a complete novice to C, and during my university work I've come across comments in code that often refer to de-referencing a NULL pointer. I do have a background in C#, I've been getting by that this might be similar to a "NullReferenceException" that you get in .Net, but now I am having serious doubts.

我是 C 的完全新手,在我的大学工作期间,我遇到过代码中的注释,这些注释通常涉及取消引用 NULL 指针。我确实有 C# 背景,我一直认为这可能类似于您在 .Net 中遇到的“NullReferenceException”,但现在我很怀疑。

Can someone please explain to me in laymans terms exactly what this is and why it is bad?

有人可以用通俗的语言向我解释一下这是什么以及为什么不好?

回答by Greg Hewgill

A NULLpointer points to memory that doesn't exist. This may be address 0x00000000or any other implementation-defined value (as long as it can never be a real address). Dereferencing it means trying to access whatever is pointed to by the pointer. The *operator is the dereferencing operator:

一个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

This is exactly the same thing as a NullReferenceExceptionin C#, except that pointers in C can point to any data object, even elements inside an array.

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

回答by Adam Rosenfield

Dereferencingjust means reading the memory value at a given address. So when you have a pointer to something, to dereference the pointermeans to read or write the data that the pointer points to.

取消引用仅意味着读取给定地址处的内存值。所以当你有一个指向某物的指针时,取消对指针的引用意味着读取或写入指针指向的数据。

In C, the unary *operator is the dereferencing operator. If xis a pointer, then *xis what xpoints to. The unary &operator is the address-ofoperator. If xis anything, then &xis the address at which xis stored in memory. The *and &operators are inverses of each other: if xis any data, and yis any pointer, then these equations are always true:

在 C 中,一元运算*符是解引用运算符。如果x是一个指针,那么*x就是x指向的对象。一元运算&符是取运算符。如果x是任何东西,则是存储在内存中&x的地址x。的*&运营商是彼此的逆:如果x是任何数据,和y是任何指针,则这些方程总是为真:

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

A null pointer is a pointer that does not point to any valid data (but it is not the only such pointer). The C standard says that it is undefined behaviorto dereference a null pointer. This means that absolutely anything could happen: the program could crash, it could continue working silently, or it could erase your hard drive (although that's rather unlikely).

空指针是不指向任何有效数据的指针(但它不是唯一的此类指针)。C 标准说取消引用空指针是未定义的行为。这意味着任何事情都可能发生:程序可能会崩溃,可能会继续静默运行,或者可能会擦除您的硬盘驱动器(尽管这不太可能)。

In most implementations, you will get a "segmentation fault" or "access violation" if you try to do so, which will almost always result in your program being terminated by the operating system. Here's one way a null pointer could be dereferenced:

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

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

And yes, dereferencing a null pointer is pretty much exactly like a NullReferenceExceptionin C# (or a NullPointerExceptionin Java), except that the langauge standard is a little more helpful here. In C#, dereferencing a null reference has well-defined behavior: it always throws a NullReferenceException. There's no way that your program could continue working silently or erase your hard drive like in C (unless there's a bug in the language runtime, but again that's incredibly unlikely as well).

是的,取消引用空指针NullReferenceException与 C# 中的 a(或NullPointerExceptionJava 中的 a)非常相似,只是语言标准在这里更有帮助。在 C# 中,取消引用空引用具有明确定义的行为:它总是抛出一个NullReferenceException. 您的程序不可能像在 C 中一样继续静默运行或擦除硬盘驱动器(除非语言运行时存在错误,但这也是极不可能的)。

回答by Lie Ryan

It means

它的意思是

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

basically, almost anything involving (*p)or implicitly involving (*p), e.g. p->...which is a shorthand for (*p). ...; except for pointer declaration.

基本上,几乎任何涉及(*p)或隐含涉及(*p),例如p->...这是(*p). ...; 除了指针声明。

回答by Prasoon Saurav

From wiki

来自维基

A null pointer has a reserved value, often but not necessarily the value zero, indicating that it refers to no object
..

Since a null-valued pointer does not refer to a meaningful object, an attempt to dereference a null pointer usually causes a run-time error.

空指针有一个保留值,通常但不一定是零值,表示它不指向任何对象
..

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

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

回答by Arun

Quoting from wikipedia:

引自维基百科

A pointer references a location in memory, and obtaining the value at the location a pointer refers to is known as dereferencingthe pointer.

指针引用内存中的一个位置,获取指针所指位置的值称为取消引用该指针。

Dereferencing is done by applying the unary *operator on the pointer.

取消引用是通过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

"Dereferencing a NULL pointer" means performing *pwhen the pis NULL

“解引用NULL指针”是指在执行*ppNULL