2012-07-20 44 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

相关问题