2014-01-16 83 views
2

當我推_Tp類型的對象回到std::vector,段故障信號產生SIGSEGV圍繞下面的代碼片斷的端部,其中template new_allocator<_Tp>回報:怪異段故障::矢量

pointer 
    allocate(size_type __n, const void* = 0) 
    { 
    if (__n > this->max_size()) 
    std::__throw_bad_alloc(); 

    return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); /* SEGMENT FAULT! */ 
    } 

持續監控關於下面的表達式產量

(this->max_size()) = 1343857 
(__n) = 4 
(sizeof(_Tp)) = 3196 
__n * sizeof(_Tp) = 12784 

我可以告訴內存顯然是足夠的,所有寄存器都很好。

但是,這個段的故障DID不會發生,直到推了幾次,因爲我認爲矢量最初大到足以推動沒有::operator new直到現在。但是,只要有return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp))),就會發生不好的事情。

儘管如此,關於_Tp的一個事實是它確實是一個沒有DEFAULT CONSTRUCTOR的類實現,因爲它具有某個引用類型的成員字段,並且不能默認構造它。根據static_cast<_Tp *>operator new(全局原創,未在我的代碼中被覆蓋)的語義,這可能與段錯誤有關嗎?我應該爲自己實現一個_Tp類型的分配器還是有其他解決方法而感到困擾?謝謝。

隨着

Ubuntu 12.04 x86-64, GCC 4.6.3, IDE Netbeans 7.4, std=C++98 
+0

這是你在那裏的一個巨大的類,但沒有默認的構造函數會在編譯時出現問題。 – chris

回答

3

allocate功能在這種情況下,剛剛分配內存 - 還沒有建造在該位置的對象。它調用全局運算符new - 而不是您類型的構造函數。然後,它將使用placement new來在結果內存塊中構造對象。

如果您在此處遇到分段錯誤,則表示您內存不足,或者程序損壞了堆。破壞堆會導致未定義的行爲,並且經常會在您的程序中遠離您損壞的地方。這裏最常見的原因可能是在釋放內存後使用內存;至少在使用free'd空間來跟蹤分配的系統上(例如dlmalloc,最常見的* nix分配器)。另一個常見的原因是試圖將先前由分配器遞交的緩衝區的末尾註銷。

你不妨考慮在valgrind下運行這個程序。

+0

儘管如此,「placement new」如何與沒有默認構造函數或重載的new運算符的類一起使用? –

+0

你顯示的片段只是分配原始內存。向矢量添加元素將執行新的位置以調用複製構造函數。 –

+0

不應該在內存不足的情況下拋出異常? – UldisK