当指针被赋值为 0 时操作系统/调试器会做什么?
8 回答
这解决的基本问题是并非所有 CPU 都实现相同类型的内存取消引用语义。free()
在某些情况下,在地址出现任何看起来像错误的情况后,无法取消引用该地址。在嵌入式处理器上尤其如此。在其他情况下,出于性能原因,分配器可能非常懒惰地将释放的内存返回给主机操作系统。
从根本上说,取消引用这样的指针可能会导致实际看到已释放的区域、看到归零的区域、看到后续分配返回的内存或导致 cpu 异常。由于这种可能性是完全合理的,c++ 已将此条件指定为“未定义行为”。
要摆脱这种情况,您需要一种方法来区分已释放或分配的指针值。因此,C++ 要求取消引用已分配的指针0
是错误的,并且将此类指针转换为整数也返回零。
回复:您当前的编辑。
出于操作系统的目的,指针不存在。在最低级别,没有任何类型的字符串、整数、浮点数或指针。只有字节。当您编写一个将 0 分配给指针值的 c++ 程序时,操作系统根本不会进入等式。这完全取决于编译器的实现。
另一方面,当您在程序中取消引用此类指针时,c++ 要求这是一个运行时错误。在嵌入式系统上,这基本上是不实际的,0 是此类系统上完全有效的内存地址,通常 SRAM 靠近该地址。如果编译器严格执行标准,它可能会在每次取消引用之前插入检查以查看它是否为空,并将 MCU 置于错误状态,但这是不寻常的,因为它会减慢已经很慢的系统并增加程序大小。
在功能更齐全的系统上,那些具有内存管理单元的系统上,应用程序中的零地址通常不会映射到任何物理页面,因此操作系统确实可以帮助您,通过在页面程序中引发段错误来尝试访问空指针值。
指向 0 的指针称为空指针,通常用于表示它没有指向任何东西。这可以通过调试器/运行时/编译器/任何东西来检查,以确保您没有指向无效数据的指针。这只是一个明确的认识,即指针现在不应该指向任何东西。
将 0(或 NULL,或根据您的导入为您预定义的任何内容)分配给指针是用于指示的一般约定:
- 指针未使用(未指向感兴趣的内存地址),
- 并且它不应该被取消引用。
我想它对程序员比对操作系统/调试器更有用。
操作系统/调试器不关心指针指向的位置。
但是检查指针是否指向有意义的地方对您很有用。
Simply, to add to this long list of answers, the runtime will assign 0
, or NULL
to the pointer. The memory at the other end, unless previously freed (free()
or operator delete
) if it was dynamically allocated (malloc()
and operator new
), or just cleaned up automatically because it was an auto
(all locals by default).
Assigning NULL
to a pointer that has valid memory at the other end creates a memory leak. A memory leak is when the OS thinks that a process is still using some memory, but the process has no handle on the memory (it has lost the address), and thus has no way of freeing it or using it. The memory will be cleaned up when the process terminates, but for long-running processes, or process that leak multiple times, or, worst of all, programs that leak large amounts of memory can cause big problems.
If a process leaks enough memory, at the least it will make the system sluggish and force the user to kill it, in worse circumstances, it would invoke the OOM killer (on systems with one), or worse, crash the entire system because of lack of memory. Also, if you dereference a NULL
pointer, on any modern OS you will cause a segfault or bus error, and on ancient OS', you could destroy the system (eg. DOS).
Debuggers may notify you if they have enough information, you can also use static analysis tools to find memory leaks, or runtime tools like valgrind. Memory leaks are one of the biggest problems for C/C++ programs, and are something to look for carefully before realeasing code.
将指针设置为 0 并不能解决悬空指针问题。如果代码认为悬空指针(根据定义无效)是有效的,设置为 0 并取消引用仍然会导致程序表现出非法行为。
如果代码在取消引用之前碰巧检查指针是否为空,那么将指针设置为 0 可以避免非法行为。
空指针比约定更重要。你可以释放一个 nullptr 并且让它不做任何事情。它也被用作指针尚未指向任何东西的约定。
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.