[英]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
我有几个问题无法回答:
NULL指针在c/c++中是否总是等于0?
如果 0 恰好是一个变量的地址会怎样?
输出似乎是结构成员的偏移地址。 这个是怎么算出来的。 我的意思是 p->c 是 c 的地址,它不存在,因为 p == NULL。如果 c 的地址不存在,你怎么能通过 &p->c 得到 c 的地址?
取消引用 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计划中这样做。
空指针常量是一个整数常量表达式,其计算结果为零(如0或0L),或者将此类值转换为void *(如(void *)0)。
2.这非常不可能,部分原因是虚拟内存,并且可能在编译器中被阻止。 3.编译器可能会实现具有偏移量的结构。 此外,您不是取消引用指针,只取地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.