我遇到了这个有线代码而且没有崩溃。
#include struct s { char* c; char* c2; }; int main() { struct s* p = NULL; printf("%dn", &(p->c)); printf("%dn", &p->c2); printf("%dn", &(*p).c2); return 0; }
输出:
0 4 4
我有几个问题来找我,我无法回答:
不,取消引用空指针不能保证崩溃。
首先,在许多情况下,编译器能够优化解除引用操作。 在您的情况下, &(p->c)
名义上取消引用空指针,但是然后获取结果的地址(在选择指向结构的成员之后)。 据推测,编译器用数字替换整个表达式,数字是结构中成员的偏移量。 (不能保证空指针指向地址0,或者它将以这种方式进行优化,但它恰好在您的系统上执行。)
这是标准offsetof
宏的通用实现的基础。 它不能在便携式标准C或C ++中实现,但实现通常使用这样的系统特定技巧 – 只要它在该系统上产生正确的结果,它就完全有效。
其次,即使您实际取消引用空指针,行为也是未定义的 。 这可能意味着你的程序崩溃,但就语言标准而言,它可以做任何事情。
过去有一些系统(可能还有),其中空指针指向地址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.编译器可能会实现具有偏移量的结构。 此外,您不是取消引用指针,只取地址。
以上就是c/c++开发分享取消引用NULL指针是否保证在C / C ++中崩溃程序?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545922.html