类析构函数中的错误

时间:2010-12-03 14:27:56

标签: c++ class pointers memory-leaks destructor

我刚刚开始我的容器类,我已经遇到了问题:

class Container
{
    private:

    string* BasePointer; // The starting pointer.
    unsigned int Capacity; // The number of values the container can hold.

    public:

    Container() // Default constructor.
    {
        Capacity = 1;
        BasePointer = new string[Capacity];
    }

    ~Container() // Destructor.
    {
        delete BasePointer; // Delete the container to prevent memory leaking.
    }
};

我收到错误Container Classes(26467) malloc: *** error for object 0x100100088: pointer being freed was not allocated。我做错了什么?

5 个答案:

答案 0 :(得分:7)

XXX ptr = new XXX[size]应与数组版本delete [] ptr匹配,而不仅仅是常规delete

在C ++中阅读free store management,正如詹姆斯提醒我们的那样 - 在这种情况下请关注rule of three

答案 1 :(得分:4)

你必须使用删除[]

delete[] BasePointer;

答案 2 :(得分:2)

其他人提到您new[]delete不匹配,您必须将delete更改为delete[]才能解决问题。但是,这只是您的第一个问题。

您还需要实现(或至少声明为私有)复制构造函数和复制赋值运算符。否则,请考虑执行此操作时会发生什么:

{
    Container c1;
    Container c2(c1);
}   // c2.~Container(); // frees the memory pointed to by 'BasePointer'
    // c1.~Container(); // also frees the memory pointed to by 'BasePointer'.

由于BasePointerc1的{​​{1}}成员都指向同一个数组,因此会释放两次。

有一些更易于使用的替代方案:

  • 考虑在可能使用动态分配的数组的任何地方使用c2。由于您的类被称为std::vector,我假设您正在尝试实现拥有资源的容器,因此您可能不想使用它。

  • 考虑使用Containerboost::scoped_ptr(如果您的编译器支持它)来管理指针的所有权。这两个都抑制了隐式声明的复制构造函数的生成,如果您实际尝试使用它们,则强制您实现自己的复制构造函数。

即使您正在实施std::unique_ptr,您仍然应该利用更原始的容器来为您完成繁重的工作(或者,至少重新实现这些原始容器,以便将繁重的工作整合成一个小的一套公用事业)。

最后,作为一个风格点,您不需要将Container用于容器。标准库提供malloc,可用于为对象分配空间和构造对象。

答案 3 :(得分:1)

如果你创建数组,你必须使用delete [] BasePointer;

答案 4 :(得分:0)

要比其他更明确 - 当您new - 编辑数组类型时,您需要使用delete[]删除指针。

这不仅发生在使用new T[size]时,请考虑以下示例:

typedef int T[42];
int* x = new T;
delete[] x; // needs delete[] though you used new without []

一般来说,如果你的对象“拥有”它通过指针保存的对象,你应该考虑使用智能指针(如boost :: scoped_array)。这样,您不必担心解构,抛出异常时会发生什么,实现赋值操作和复制构造函数......