2012-07-20 83 views
0

我有一個簡單的類:重置對象m_object = Object(new,parameters);

class Histogram { 
    int m_width; 
    int m_height; 
    int m_sampleSize; 
    int m_bufferWidth; 
    int m_bufferHeight; 

    uint8* m_buffer; 
    int m_size; 
public: 
    Histogram() : m_buffer(0) { } 
    Histogram(int width, int height, int sampleSize) { 
     m_buffer = new unsigned char [width*height*sampleSize]; 
    } 
    ~Histogram() { 
     my_log("destructor: buffer: %p", m_buffer); 
     if (m_buffer) { delete [] m_buffer; m_buffer = NULL; } 
    } 
    unsigned char* buffer() { 
     return m_buffer; 
    } 
}; 

它是在其他類中的成員:

class Other { 
    Histogram m_histogram; 

    void reset() { 
     my_log("reset() called: buffer: %p", m_histogram.buffer()); 
     m_histogram = Histogram(512, 512, 2); 
    } 
} 

現在,我首先使用直方圖創建「未初始化的」對象()構造 - 其中規定m_buffer爲NULL ;

然後,我調用重置方法,它會執行m_histogram =直方圖(512,512,3) - 新對象具有通過new初始化的m_buffer。

所以預計日誌消息的順序是:

  • 「復位()調用:緩衝液:爲0x0」
  • 「析:緩衝區:爲0x0」

但是,相反,我得到:

  • 「復位()調用:緩衝液:爲0x0」
  • 「析構函數:BU ffer:0x072a7de「

因此,一些不合理的行爲正在執行。此外,我還刪除了第二個對象(用「較大」構造函數創建,帶有三個int參數)時顯示0x072a7de地址。

+0

由編譯器生成的默認拷貝構造函數和賦值運算符不能很好地使用指針。你需要遵守'三條規則'(或者C++ 11中的五條規則),請參閱:http://stackoverflow.com/a/255744/14065 – 2012-07-20 07:05:38

回答

1

首先,既然你都指向一個動態分配的數組,你需要使用運營商delete[]

delete[] m_buffer; 

其次,更重要的是,既然你動態分配的內存,您應該遵循rule of three和實現複製構造函數和賦值運算符,以及修復析構函數。

現在發生的事情是你的(編譯器合成的)賦值操作符正在做一個「淺」拷貝,即它正在拷貝指針。然後,你將擁有多個析構函數試圖刪除它。您正在調用未定義的行爲。

通過使用std::vector<uint8>作爲緩衝區,您真的可以節省很多麻煩。

+0

對不起,我在oryginal代碼中使用了delete []。至於其餘部分,我認爲會出現以下順序:a)刪除舊的m_histogram,b)構造新的直方圖(512,...),c)將其複製到m_histogram使用的空間。它也可以直接在舊空間中創建新的直方圖。你的回答指出,a)是作爲最後一步完成的? – GameTCoder 2012-07-20 07:06:26

+0

@GameTCoder表達式的RHS創建新的直方圖,但賦值運算符用於分配給LHS。這只是製作了RHS指針的淺表副本。 RHS是一個臨時的並被刪除,所以你在LHS中留下了一個懸掛指針。 – juanchopanza 2012-07-20 07:11:21

+0

謝謝!這解釋了意想不到的行爲。 – GameTCoder 2012-07-20 07:13:50

2

你必須意識到拷貝構造函數和賦值操作符爲你的類直方圖,因爲

m_histogram = Histogram(512, 512, 2); 

是賦值運算符調用。隱式運算符=您的類的按位副本成員。

而你必須在析構函數中使用delete[],而不是delete,因爲你分配了一個數組。

+0

對不起,我在oryginal代碼中使用了delete []。 – GameTCoder 2012-07-20 07:06:43

相關問題