【问题标题】:error in class destructor类析构函数中的错误
【发布时间】:2011-05-19 18:57:36
【问题描述】:

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

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。我做错了什么?

【问题讨论】:

  • 它被称为destructor,就像在破坏中一样。不是解构器。 :)

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


【解决方案1】:

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

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

【讨论】:

  • 正是我的想法
  • 谢谢。 [] 有语法上的原因吗?它可以包含可选参数或其他内容吗?
  • 不,您不能提供参数。原因是 - 好吧,它的作用与 delete 的作用不同,所以它需要一个不同的名称;)
【解决方案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'.

由于c1c2BasePointer 成员指向同一个数组,因此它被释放了两次。

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

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

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

即使您正在实现Container,您仍然应该利用更多原始容器为您完成繁重的工作(或者,至少重新实现这些原始容器,以便将繁重的工作合并为一小组实用程序)。

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        你必须使用 delete[]

        delete[] BasePointer;
        

        【讨论】:

          猜你喜欢
          • 2012-07-04
          • 1970-01-01
          • 1970-01-01
          • 2011-02-14
          • 2015-07-09
          • 1970-01-01
          • 2012-02-05
          • 2018-09-24
          • 2013-08-13
          相关资源
          最近更新 更多