ycs*_*hao 6 c c++ null struct pointers
我遇到了这个有线代码而且没有崩溃.
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
4
4
Run Code Online (Sandbox Code Playgroud)
我有几个问题来找我,我无法回答:
在c/c ++中NULL指针总是等于0吗?
如果0恰好是变量的地址会发生什么?
输出似乎是结构成员的偏移地址.这是如何计算的.我的意思是p-> c是c的地址,它不存在,因为p == NULL.如果c的地址不存在,你怎么能通过&p-> c得到c的地址?
取消引用NULL指针是否保证在C/C++中使程序崩溃?(让我们假设在系统中)
Kei*_*son 13
不,取消引用空指针不能保证崩溃.
首先,在许多情况下,编译器能够优化解除引用操作.在您的情况下,&(p->c)名义上取消引用空指针,但您然后获取结果的地址(在选择指向结构的成员之后).据推测,编译器用数字替换整个表达式,这是结构中成员的偏移量.(无法保证空指针指向地址0,或者它将以这种方式进行优化,但它恰好在您的系统上执行.)
这是标准offsetof宏的通用实现的基础.它不能在便携式标准C或C++中实现,但实现通常使用这样的系统特定技巧 - 只要它在该系统上产生正确的结果,它就完全有效.
其次,即使您实际取消引用空指针,行为也是未定义的.这可能意味着你的程序崩溃,但就语言标准而言,它可以做任何事情.
过去有一些系统(可能还有),其中空指针指向地址0,并且系统的存储器映射被设置为使得地址0是恰好包含0值的有效存储器地址.例如,在这样的机器上,空指针就像一个指向空'\0'终止字符串的指针.当在这样的系统上工作的代码无意中依赖于这种行为时,这导致了一系列错误修复,被移植到具有更强内存保护的新系统.(我认为这可能是从基于68K的Sun 3过渡到基于SPARC的Sun 4,但我不确定.)
有关空指针的更多信息,请参阅comp.lang.c FAQ的第5节.其中大部分也适用于C++.