typedef struct {
int a;
}stTemp_t;
int main()
{
stTemp_t *pstTemp = NULL;
int *p = &(pstTemp->a); // <<----- supposedly de-ref NULL pointer
return 0;
}
上面指出的指令,我认为应该会导致段错误,但实际上并没有。我尝试使用“gcc -O0”省略默认的编译器优化。
很自然地,如果我用 int i = pstTemp->a
替换它,我会得到一个段错误。我试图通过 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
在 $3
中,我们可以看到当我尝试打印 &(pstTemp->a)
时,它似乎被解释为一个地址,因此相当于int *p = NULL
。
但是我的疑问是,语句 (pstTemp->a)
是否应该在 & 生效之前被评估并导致段错误?
最佳答案
实际上,导致代码中出现未定义行为的甚至不是取消引用空指针的行为。
当寻址 (&
) 和取消引用 (*
或 ->
) 操作紧随其后时,它们就会取消彼此并折叠成指针算法。因此,表达式&pstTemp->a
产生a
的地址。
但是,对 NULL 指针执行指针算术是未定义的行为。由于没有实际取消引用(并且该行为无论如何都是未定义的),看来编译器只是没有发出任何明显有害的代码这会导致段错误。
不要指望未定义的行为会导致任何特定的错误。它被称为未定义而不是“保证崩溃”是有原因的。
关于c - 通过空结构指针取消引用变量地址,无段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31922434/