为什么将指针0指定为悬空指针的解?

时间:2012-06-06 01:48:54

标签: c++ memory-management dangling-pointer

当指针指定0时,OS / Debugger会做什么?

8 个答案:

答案 0 :(得分:3)

这解决的基本问题是并非所有CPU都实现相同类型的内存解引用语义。在某些情况下,在将地址free()转换为看似错误的任何地址之后,无法取消引用地址。在嵌入式处理器上尤其如此。在其他情况下,出于性能原因,分配器可能对将释放的内存返回主机操作系统非常懒惰。

从根本上说,取消引用这样的指针可能会导致实际看到释放区域,看到清零区域,看到后续分配返回的内存,或导致cpu异常。由于这种可能性是完全合理的,因此c ++将此条件指定为“未定义的行为”。

要摆脱这种情况,您希望有一种方法来区分已释放或分配的指针值。因此,C ++要求取消引用已分配0的指针是一个错误,将这样的指针转换为整数也会返回零。


re:您当前的编辑。

指针不存在用于操作系统的目的。在最低级别,没有任何类型的字符串,整数,浮点数或指针。只有字节。当您编写一个将0指定给指针值的c ++程序时,操作系统根本不会进入等式。这完全取决于编译器的实现。

另一方面,当你在程序中取消引用这样的指针时,c ++要求这是一个运行时错误。在嵌入式系统上,这基本上是不实用的,0在这样的系统上是完全有效的存储器地址,通常SRAM靠近该地址。如果编译器严格执行标准,它可能会在每个取消引用之前插入一个检查以查看它是否为空,并将MCU置于错误状态,但这是不寻常的,因为它会减慢已经很慢的速度系统并增加程序大小。

在功能更全面的系统中,具有内存管理单元的系统,应用程序中的零地址通常不会映射到任何物理页面,因此操作系统通过在页面程序中引发段错误来帮助您它试图访问空指针值。

答案 1 :(得分:2)

指向0的指针称为空指针,通常用于指示它没有指向任何东西。这可以由调试器/运行时/编译器/检查,以确保您没有指向无效数据的指针。它只是一个明确的认识,指针不应该指向任何东西。

答案 2 :(得分:2)

为指针分配0(或NULL,或根据您的导入为您预先定义的任何内容)是一般约定,用于表示:

  • 指针未使用(未指向感兴趣的内存地址),
  • 并且不应该取消引用

答案 3 :(得分:2)

我认为它对程序员比对OS /调试器更有用。

OS /调试器不关心指针指向的位置。

但是检查指针是否指向某个有意义的地方是有用的。

答案 4 :(得分:1)

简单地说,要添加到这个长答案列表中,运行时会将0NULL分配给指针。另一端的内存,除非之前已释放(free()operator delete),如果它是动态分配的(malloc()operator new),或者只是自动清理,因为它是auto(默认情况下为所有本地人)。

NULL分配给另一端具有有效内存的指针会产生内存泄漏。内存泄漏是指操作系统认为进程仍在使用某些内存,但进程无法处理内存(它已丢失地址),因此无法释放或使用它。当进程终止时,内存将被清除,但对于长时间运行的进程,或多次泄漏的进程,或者最糟糕的是,泄漏大量内存的程序可能会导致严重的问题。

如果一个进程泄漏了足够的内存,至少它会使系统变得迟钝并强迫用户杀死它,在更糟糕的情况下,它会调用OOM杀手(在有一个系统的系统上),或者更糟糕的是,整个崩溃系统因缺乏记忆力。此外,如果您取消引用NULL指针,在任何现代操作系统上都会导致段错误或总线错误,而在古老的操作系统上,您可能会破坏系统(例如DOS)。

调试器可能会通知您是否有足够的信息,您也可以使用静态分析工具来查找内存泄漏,或运行时工具如valgrind。内存泄漏是C / C ++程序最大的问题之一,在重新发布代码之前需要仔细查找。

答案 5 :(得分:0)

将指针设置为0不能解决悬空指针问题。如果代码认为悬空指针(通过定义无效)有效,则设置为0并且取消引用仍将导致程序显示非法行为。

如果代码恰好在解除引用之前检查指针为null,那么将指针设置为0可以避免非法行为。

答案 6 :(得分:0)

空指针比惯例更重要。您可以释放nullptr并让它不做任何事情。它也被用作指针尚未指向任何东西的约定。

答案 7 :(得分:0)

Why is assigning 0 to a pointer a solution to a dangling pointer?

@ wikipedia ::

To expose dangling pointer errors, one common programming technique is to set
pointers to the null pointer or to an invalid address once the storage they 
point to has been released. When the null pointer is dereferenced 
(in most languages) the program will immediately terminate—there is no potential
for data corruption or unpredictable behavior. This makes the underlying 
programming mistake easier to find and resolve.  
This technique does not help when there are multiple copies of the pointer.  

What does the OS/Debugger do when a pointer is assigned 0?

@ wikipedia ::

though, that the physical address zero is often directly accessible by hardware (for 
instance, it is directly accessible in x86 real mode, and it is where the interrupt  
table is stored), but modern operating systems usually map virtual address spaces in 
such a way that accessing address zero is forbidden.