2011-03-04 70 views
5

我有一個類Foo對我已經重載+操作如下副本:返回與運算符重載

Foo Foo::operator+(const Bar &b) 
{ 
    Foo copy = (*this); 
    if (someCondition) return copy; 
    //snip 
} 

對我來說,這看起來是合理的。但是,每當我返回副本時,Visual Studio都會向我發出「可能由於堆損壞」導致的錯誤。我所做的是否有問題?

編輯:與更多信息更新。

錯誤消息:

Windows已經在 SAMPLE.EXE觸發一個斷點。

這可能是由於 堆的腐敗,這表明在 SAMPLE.EXE或任何它 加載的DLL的一個錯誤。

這也可能是由於用戶 按F12而sample.exe有 的重點。

輸出窗口可能有更多 診斷信息。

複製構造:

Foo::Foo(const Foo&p) 
{ 
    some_pointer = p.get_some_pointer(); 
    some_value = p.get_some_value(); 
} 

代碼它打破到:

//within dbgheap.c 
    extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
      const void * pUserData 
      ) 
    { 
      if (!pUserData) 
       return FALSE; 

      if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE)) 
       return FALSE; 

      return HeapValidate(_crtheap, 0, pHdr(pUserData)); 
    } 
+4

你能告訴我們'Foo'的拷貝構造函數嗎? – 2011-03-04 07:37:31

+1

什麼是錯誤代碼? – metdos 2011-03-04 07:42:29

+0

@ Space_C0wb0y @metdos我已更新了更多信息 – socks 2011-03-04 07:50:49

回答

3

這類型的錯誤通常與的多個缺失(或釋放)相關聯的相同的指針或一些更隱晦的情況(從一堆獲取並釋放到不同的堆中,但這可能不是這種情況)。

我會做的第一件事是看一個析構函數,並檢查你是不是淺拷貝和雙刪除。例如,使用以下代碼:

// buggy!!! 
struct test { 
    int * data; 
    test() : data(new int[5]) {} 
    ~test() { delete [] data; } 
    test(test const & rhs) : data(rhs.data) {} 
    test& operator=(test const & rhs) { 
     data = rhs.data; 
    } 
}; 
int main() { 
    test t1;   // 5 ints allocated int t1.data 
    test t2(t1); // no memory allocated, t2.data == t1.data 
} // t2 out of scope: t2.~test() => delete t2.data 
    // t1 out of scope: t1.~test() => delete t1.data but both are the same: double delete 

如果是這種情況,您可以決定是否要淺拷貝或進行深拷貝。在第二種情況下,複製構造函數(和賦值運算符)應該分配它們自己的內存,而在第二種情況下,您必須確保內存不會被釋放兩次。

與指針一樣,最好將資源管理委託給外部(預先構建的)類。如果是獨特的所有權(和深層副本),則應該使用std::auto_ptr(或者在C++ 0x中爲std::unique_ptr或者增強變體)。在第二種情況下,使用boost::shared_ptr(或在C++ 0x中爲std::shared_ptr)將確保數據共享並且只能刪除一次。

+1

如果類不擁有指針所指向的對象,那麼首選參考。 – 2011-03-04 09:06:55

+1

@Space:一個首選項,將有效地呈現類不可分配(這可能是一個算術運算符的類奇怪)... – visitor 2011-03-04 11:33:08

+0

@visitor:對,沒有考慮到這一點。 – 2011-03-04 11:36:53