访问值为 Null 的指针和访问它指向的对象之间有什么区别?

What is the Difference between accessing a Pointer whose value is Null and accessing what it points to?

int x; 
int* px = &x; 
int* pn = nullptr; 
if (px==px) { do something;} 

By accessing I mean dereferencing

取消引用空指针是未定义的行为

I never experienced any crashes or bugs related to that

该程序有未定义的行为,这意味着它仍然存在错误,即使它没有明确说明并且“似乎正在运行”。

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。

因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。


1有关未定义行为的更准确的技术定义,请参阅 this 其中提到:没有对程序行为的限制.

示例代码(此时由 OP 公开)有点混乱。

因此,我想在 允许和不允许的情况下添加一些示例:

#include <iostream>

int main()
{
  int x = 0; // make some storage
  int* px = &x; // px initalized with address of x     -> OK.
  int* pn = nullptr; // pn initialized with nullptr    -> OK.
  if (px == px) { /* ... */ } // senseless but         -> OK.
  if (px == pn) { /* ... */ } //                       -> OK.
  std::cout << *px; // dereference a valid pointer     -> OK.
  std::cout << *pn; // dereference a null pointer      -> UNDEFINED BEHAVIOR!
  px = pn; // assign a (null) pointer                  -> OK.
  std::cout << *px; // dereference a null pointer      -> UNDEFINED BEHAVIOR!
  // ...and finally a common bug...
  int* py = nullptr; //                                -> OK.
  { int y = 1; // storage with limited life-time       -> OK.
    py = &y; // assign address of storage              -> OK.
  } // scope end -> life-time of y ends                -> OK.
  // Attention! This makes py dangling (pointing to released storage).
  if (py /* != nullptr*/) { // This doesn't help. py is not a null pointer.
    std::cout << *py; // access after end of life-time -> UNDEFINED BEHAVIOR!
  }
}

编译器 (g++ 11.2) 的输出:

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp # && ./a.out # Compile but don't exec. It contains UNDEFINED BEHAVIOR!
main.cpp: In function 'int main()':
main.cpp:8:10: warning: self-comparison always evaluates to true [-Wtautological-compare]
    8 |   if (px == px) { /* ... */ } // senseless but         -> OK.
      |       ~~ ^~ ~~

Demo on coliru