2014-10-20 63 views
1

我正試圖實施一項技術來測試http://www.codeproject.com/Articles/6108/Simulating-Memory-Allocation-Failure-for-Unit-Test中描述的失敗運算符new當新操作員失敗時的構造函數調用

這是被測試的樣本代碼:

VArray* arr = new VArray(1U, 3U, true); 

我可以做,而不是分配內存new回報NULL。在這種情況下,程序應該繼續到下一行(應測試是否爲arr == NULL),這正是MSVC中的做法。

但是,VArray的構造函數仍然在GCC中失敗的new之後調用。並且因爲thisNULL,它會在第一次分配給屬性時產生SIGSEGV。這似乎是錯誤的行爲根據C + + 03標準:https://stackoverflow.com/a/11514528/711006

我的實施運營商newdelete下面。

unsigned int OperatorPlainNewFailsAfter = UINT_MAX; 

void* operator new(const size_t _size) throw() 
{ 
    void* result; 
    if(OperatorPlainNewFailsAfter == 0U) 
    { 
    result = NULL; 
    } 
    else 
    { 
    result = malloc(_size); 
    OperatorPlainNewFailsAfter--; 
    } 
    return result; 
} 

void operator delete(void* _memory) throw() 
{ 
    free(_memory); 
} 

我想念什麼?

+6

替換'operator new'必須在失敗時拋出'std :: bad_alloc'。返回NULL值違反了合同。「需要的行爲:返回一個非空指針到合適對齊的存儲區(3.7.4),否則拋出一個'bad_alloc'異常。**這個需求綁定到這個函數的替換版本**上。 – 2014-10-20 08:50:56

回答

3

C++標準要求分配函數(如基本operator new)通過拋出std::bad_alloc異常(如果失敗)而失敗。不允許返回空指針。當你返回一個空指針時你有未定義的行爲,是的,一個可能的結果是調用構造函數。

+0

感謝您的提示,但我的初衷是替換'新(std :: nothrow)',我同意我已經完成了一半。所以你幫我正確完成了。 – Melebius 2014-10-20 09:18:36

1

如果被調用的operator new被聲明爲throw(),那麼 編譯器不檢查空指針是錯誤的。 但是聲明非放置的新文件throw()是非法的,所以 編譯器檢查它沒有意義;如果有的話, 應該在看到聲明時發出抱怨,因爲 非放置operator new被隱式聲明。

如果你想測試未能new(這是一個好主意), 您operator new函數不應該返回一個空指針, 但應該拋出std::bad_alloc。否則,你不是 測試同樣的事情。在您網站的頁面上,測試代碼 使用新的展示位置。該代碼仍然是非法的, ,因爲他的operator new可能會返回一個空指針而沒有 宣佈功能throw(),但很容易 固定。 (或不他呼籲::operator new,而不是 malloc,對於實際分配,而這個功能可能 扔他還呼籲::operator new函數來分配, 但使用的::delete運營商去免費;如果你調用 ::operator new )當然,即使是固定的,它也不會測試 任何有用的東西,因爲你需要知道的是,你的 程序對std::bad_alloc反應正確,而不是它對 正確反應空指針,它永遠不會看到。

+0

謝謝您對原始示例的徹底檢查。是的,我修改了它,因爲放置'new'不是我想測試的東西。由於我正在替換「基本」全局'new',所以我無法調用':: operator new',因爲它被替換!這就是'malloc'和'free'的原因。 – Melebius 2014-10-20 09:28:59

相關問題