2016-07-22 116 views
4

考慮到下面的代碼,在nullptr上做指針運算是否安全?nullptr和指針算術

我想添加任何偏移量爲nullptr導致另一個nullptr,到目前爲止MSVC產生的結果如我所料,不過我有點不確定使用nullptr這樣是否安全:

float * x = nullptr; 

float * y = x + 31; // I assume y is a nullptr after this assigment 

if (y != nullptr) 
{ 
    /* do something */ 
} 

回答

10

你沒不要定義「安全」對您意味着什麼,但不管您提出的代碼具有未定義的行爲。指針算術只允許指向數組對象的指針值,或者指向數組的一個末尾。 (對於此規則,非數組對象被認爲是一個元素的數組)。

由於空指針永遠不是對象的地址或通過對象的地址,因此您的代碼永遠不會有定義良好的行爲。

+0

'int * a; a ++;'是UB,即使我不取消引用指針?你能給一個參考嗎? – user463035818

+4

@ tobi303:沒有參考,因爲標準沒有明確說明它是未定義的。 [expr.add]/5定義了指針+ integer * only *對指向數組的指針(或指向對象,其作爲1的數組)的行爲。如果指針未指向數組,則根據定義,行爲是未定義的(除了在加0的情況下,對所有指針定義的[expr.add]/8)。 –

+3

@ tobi303 UB並不意味着「崩潰」,它的意思是「我們沒有定義這是什麼」。碰巧,編譯器可以積極地優化和檢測UB,並導致程序出乎意料地行爲。一所優化學校「因爲UB不能在良好的程序中出現,所以導致UB的任何邏輯鏈都可以安全地消除,直到並且包括在代碼中跳過明確的」if「檢查。簡而言之,UB會導致*時間旅行*錯誤,遠離UB的代碼的行爲方式與您編寫的代碼不匹配。 – Yakk

1

不,將偏移量添加到nullptr不會導致nullptr。這是未定義的行爲。

+2

添加非零偏移量不會導致nullptr是正確的。然而,向空指針加零/從零指針中減去零是明確定義的,併產生一個空指針(這是C和C++之間的一個特定區別 - 在C中這是未定義的)。 – Peter

1

...在nullptr上做指針運算是否安全?

不,算術nullptr沒有很好的定義,因爲它本身不是一個指針類型(但轉換爲所有指針類型的NULL值存在)。

See here;

std::nullptr_t是空指針文字的類型,nullptr。它是一種獨特的類型,它本身不是指針類型或指向成員類型的指針。


一般情況下,任意的指針運算(甚至NULL值)幾乎肯定會導致問題 - 你沒有分配內存 - 這是不是你嘗試讀取或寫入。

出於比較目的(例如,結束時),您將會很好,但否則您的代碼將導致未定義的行爲。

欲瞭解更多信息,請參閱維基百科undefined behavior

+0

我不確定第二段中的邏輯:指針算術不會導致從內存讀取或寫入內存。記憶與OP的問題無關。 –

+0

這更多的是關於OP的任意部分問題。我會把它清理乾淨。 – Niall

2
is it safe to do pointer arithmetic on nullptr? 

C++ 限定兩種上nullptr操作。適用於:

float * x=nullptr; 
float * y=nullptr; 
  1. x +/- 0 = x

  2. x-y=0 //note x and y have the same type

你不能對什麼是沒有定義的假設,所以你不應該這樣做。

+1

實際上,還有第三個操作定義爲:'x == y'。看起來微不足道,但它確實意味着只有一個空指針值。 – MSalters