[英]dereference variable address through null structure pointer, no segmentation fault
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
替換它,我會得到一個seg-fault。 我試圖運行上面的程序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
在$3
,我們可以看到當我嘗試打印&(pstTemp->a)
,它似乎被解釋為一個地址,因此相當於int *p = NULL
。
但是我懷疑的是,在&生效之前是否應該對語句(pstTemp->a)
進行評估並導致seg-fault?
實際上,它甚至不是解除引用代碼中導致未定義行為的空指針的行為。
當地址( &
)和解除引用( *
或->
)操作立即相互跟隨時,它們相互抵消並折疊成指針算術。 因此,表達&pstTemp->a
產生的地址a
。
但是, 對NULL指針執行指針運算是未定義的行為。 由於沒有進行實際的解除引用(並且行為未定義),編譯器似乎沒有發出任何會導致分段錯誤的明顯有害的代碼。
不要指望未定義的行為會導致任何特定錯誤。 它被稱為未定義而不是“保證崩潰” 的原因。
這是未定義的行為。
它不會在這里崩潰,因為沒有實際的解引用,我們只取(pstTemp->b)
的地址 ,這實際上是b
字段的偏移量(最可能是4,取決於int
和編譯器的大小) 。
嘗試這個:
typedef struct {
int a;
int b;
} stTemp_t;
int main()
{
stTemp_t *pstTemp = NULL;
int *p = &(pstTemp->b);
printf ("%p", p);
return 0;
}
Te輸出很可能是:
00000004
但
printf ("%d", pstTemp->b);
很可能會崩潰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.