c - 通过空结构指针取消引用变量地址,无段错误

标签 c pointers null 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;
}

上面指出的指令,我认为应该会导致段错误,但实际上并没有。我尝试使用“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/

相关文章:

c - 为什么动态分配的int数组在scanf、c语言中使用&?

c - minGW项目中w32api有什么用

python - 在 Python 中, 'return self' 返回对象的副本还是指针?

c++ - 简单的 C++ 指针转换

hadoop - 在发送到 channel 之前删除空的 Flume 事件

c - 如何在服务器端显示客户端IP地址?

c - 为什么我的变量在 strtok() 和 fgets() 之后改变而不修改它?

sscanf() 中的字符指针

java - 需要帮助来发现java空指针异常

C# - 如何使用正则表达式替换 NULL 字符?