簡體   English   中英

通過空結構指針取消引用變量地址,沒有分段錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM