通过空结构指针取消引用变量地址,没有分段错误

Jit*_*dra 4 c null pointers segmentation-fault dereference

typedef struct {
    int a;
}stTemp_t;

int main()
{
stTemp_t *pstTemp = NULL;
int *p = &(pstTemp->a);       // <<----- supposedly de-ref NULL pointer

return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面指出的指令,我认为应该引起一个它没有的分段错误.我尝试使用"gcc -O0"省略默认的编译器优化.

当然,如果我用它替换它int i = pstTemp->a,我会得到一个段错误.我试图运行上面的程序throgh gdb来弄清楚发生了什么,以下是我的观察 -

(gdb) p pstTemp
$2 = (stTemp_t *) 0x0
(gdb) p pstTemp->a
Cannot access memory at address 0x0
(gdb) p &(pstTemp->a)
$3 = (int *) 0x0
Run Code Online (Sandbox Code Playgroud)

在这里$3,我们可以看到,当我尝试打印时&(pstTemp->a),它似乎被解释为一个地址,因此相当于int *p = NULL.

不过我怀疑的是,该声明是否应该(pstTemp->a)在生效之前得到评估并导致段错误?

The*_*ant 7

实际上,它甚至不是解除引用代码中导致未定义行为的空指针的行为.

当地址(&)和解除引用(*->)操作立即相互跟随时,它们相互抵消并折叠成指针算术.因此,表达式&pstTemp->a产生地址a.

但是,对NULL指针执行指针运算是未定义的行为.由于没有进行实际的解除引用(并且行为未定义),编译器似乎没有发出任何会导致分段错误的明显有害的代码.

不要指望未定义的行为会导致任何特定错误.它被称为未定义而不是"保证崩溃" 的原因.