繁体   English   中英

取消引用 NULL 指针是否保证使 C/C++ 中的程序崩溃?

[英]Does dereference a NULL pointer guarantee to crash a program in C/C++?

我遇到了这个有线代码,它没有崩溃。

#include <stdio.h>
struct s
{
    char* c;
    char* c2;
};

int main()
{
    struct s* p = NULL;
    printf("%d\n", &(p->c));
    printf("%d\n", &p->c2);
    printf("%d\n", &(*p).c2);
    return 0;
}

Output:

0
4
4

我有几个问题无法回答:

  1. NULL指针在c/c++中是否总是等于0?

  2. 如果 0 恰好是一个变量的地址会怎样?

  3. 输出似乎是结构成员的偏移地址。 这个是怎么算出来的。 我的意思是 p->c 是 c 的地址,它不存在,因为 p == NULL。如果 c 的地址不存在,你怎么能通过 &p->c 得到 c 的地址?

  4. 取消引用 NULL 指针是否保证使 C/C++ 中的程序崩溃?(假设在系统中)

不,取消引用空指针不能保证崩溃。

首先,在许多情况下,编译器能够优化取消引用操作。 在你的情况下, &(p->c)名义上取消引用空指针,但是然后你获取结果的地址(在选择指向结构的成员之后)。 据推测,编译器用数字替换整个表达式,这是结构中成员的偏移量。 (无法保证空指针指向地址0,或者它将以这种方式进行优化,但它恰好在您的系统上执行。)

这是标准offsetof宏的通用实现的基础。 它不能在便携式标准C或C ++中实现,但实现通常使用这样的系统特定技巧 - 只要它在该系统上产生正确的结果它就完全有效。

其次,即使您实际取消引用空指针,行为也是未定义的 这可能意味着你的程序崩溃,但就语言标准而言,它可以做任何事情。

过去有一些系统(可能还有),其中空指针指向地址0,并且系统的存储器映射被设置为使得地址0是恰好包含0值的有效存储器地址。 例如,在这样的机器上,空指针就像一个指向空的'\\0'终止字符串的指针。 当在这样的系统上工作的代码无意中依赖于这种行为时,这导致了一系列错误修复,被移植到具有更强内存保护的新系统。 (我认为这可能是从基于68K的Sun 3过渡到基于SPARC的Sun 4,但我不确定。)

有关空指针的更多信息,请参阅comp.lang.c FAQ的第5节。 其中大部分也适用于C ++。

您实际上并没有取消引用指针。 这就是代码没有崩溃的原因。 代码的作用是获取struct成员的偏移量。 第一个成员的偏移量为0字节,第二个成员的长度为4个字节。

c标准不保证NULL指针定义为0,它是实现定义的。 (201x:7.19)

在C ++中,空指针始终为0。

在C中,NULL指针可能不是0,但我从未见过这样的系统。

在所有使用虚拟内存的现代系统中,取消引用空指针都会崩溃。 但你没有在你的BTW计划中这样做。

  1. NULL始终为零: http//www.cplusplus.com/reference/cstring/NULL/

空指针常量是一个整数常量表达式,其计算结果为零(如0或0L),或者将此类值转换为void *(如(void *)0)。

2.这非常不可能,部分原因是虚拟内存,并且可能在编译器中被阻止。 3.编译器可能会实现具有偏移量的结构。 此外,您不是取消引用指针,只取地址。

  1. 当然,NULL始终为0.除非您将其定义为其他内容。
  2. 我认为现在不允许将页面映射为0,但如果允许,则可以在地址0处有一个变量。
  3. 你看,你从未真正访问过p指向的变量。 你只想要他们的地址。 它们可以从p计算出来。 一个指针需要4个字节(在你的平台上),所以我们知道结构偏移中的第一个指针是0,第二个是4,等等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM