2014-06-26 74 views
4

根據C++ 11(由於使用const_cast,請參見下面的引用),以下代碼是否構成「未定義行爲」?全局分配函數和const void *

const void* p = operator new(123); 
operator delete(const_cast<void*>(p)); 

從C++ 11標準(3.7.4.2.3)有關報價:

供給至解除分配函數可以是空指針值的第一個參數的值;如果是這樣,並且如果釋放功能是標準庫中提供的功能,則該呼叫不起作用。否則,行爲理解過程連接定義,如果在標準庫提供給operator delete(void*)值不是由任operator new(std::size_t)operator new(std::size_t, const std::nothrow_t&)以前調用標準庫

如果答案是否定的返回值之一,請提供來自C++ 11標準的引用證實了這一點。

+3

我不明白爲什麼你投'p' – EoiFirst

+0

我不明白這一點。傳遞給'operator delete' *的值是* operator new返回的值,完全按照需要。無論你想要什麼,你都可以自由地來回投射。 – molbdnilo

+0

@EoiFirst因爲OP正在調用'operator delete',而不是使用'delete'表達式。 – Angew

回答

4

它不是未定義的。其理由是這樣的:

  1. operator new返回void*,因此它被保證返回修改的(非const)存儲器:[support.dynamic]

    void* operator new(std::size_t size); 
    
  2. const_cast其中施放如果被引用的對象不是const,那麼離開常量是有效的:[expr.const.cast]§7,引用[dcl.type.cv],特別是§3+ 4

    3對cv-qualified類型的指針或引用不需要實際指向或引用cv-qualified對象,但它被視爲如同它一樣對待;即使引用的對象是非常量對象並且可以通過其他訪問路徑修改,也不能使用const限定的訪問路徑來修改對象。

    4除了任何聲明爲mutable(7.1.1)的類成員都可以修改外,任何嘗試在其生命週期(3.8)內修改對象的嘗試都會導致未定義的行爲。

  3. const_cast不修改的操作數的值:[expr.const.cast]§3:

    ...指針的結果 const_cast指原始對象。

+0

是否「指針const_cast的結果引用了原始對象」這一事實。意味着它是「先前調用操作符new [...]」返回的值之一? – zch

+0

@zch當然。該值不會更改。 – Angew

+1

那麼,文本只能保證指針指向同一個對象。我想知道是否可以有兩個不同的指針類型值(兩個不同的地址)指向同一個對象。 3.9.2/3「對象指針類型的有效值表示內存中的字節地址(1.7)或空指針(4.10)。」。實際上,我認爲在某些系統中,你可以在兩個地址上映射相同的內存。 – zch