取消引用空指针

时间:2010-05-24 11:43:52

标签: c++ c null pointers

int* p = 0;
int* q = &*p;

这是未定义的行为吗?我浏览了一些相关问题,但这个具体方面没有显示出来。

4 个答案:

答案 0 :(得分:50)

这个问题的答案是:它取决于你遵循的语言标准: - )。

在C90和C ++中,这是无效的,因为你对空指针执行间接(通过执行*p),这样做会导致未定义的行为。

但是,在C99中,此 有效,格式正确且定义明确。在C99中,如果一元的操作数 - &是作为应用一元 - *或执行下标([])的结果而获得的,那么&都不是也不会应用*[]。例如:

int* p = 0;
int* q = &*p; // In C99, this is equivalent to int* q = p;

同样地,

int* p = 0;
int* q = &p[0]; // In C99, this is equivalent to int* q = p + 0;

来自C99§6.5.3.2/ 3:

  

如果[一元&运算符]的操作数是一元*运算符的结果,则不会对该运算符和&运算符进行求值,结果就好被省略,除了对运算符的约束仍然适用且结果不是左值。

     

同样,如果操作数是[]运算符的结果,则&运算符和*隐含的一元[]都不会被评估,结果就像删除了&运算符并将[]运算符更改为+运算符一样。

(及其脚注,#84):

  

因此,&*E相当于E(即使E是空指针)

答案 1 :(得分:3)

是的,这将是未定义的行为,但您的编译器可能会优化&*

为什么它未定义,是你试图访问可寻址空间之外的内存。

答案 2 :(得分:-1)

是的,取消引用空指针是未定义的行为。指针上下文中的整数常量0是空指针。就是这样。

现在,如果您的第二行是int *q = p;,那将是一个简单的指针赋值。如果编译器删除了&*并减少了对赋值的取消引用,那么你就可以了。

答案 3 :(得分:-1)

恕我直言,就这两个代码行而言,地址空间之外没有任何访问权限。第二个陈述只是取(* p)的地址再次为'p',因此它将存储'0'。但该位置永远不会访问