【问题标题】:C++ Destructors , dynamic allocationC++析构函数,动态分配
【发布时间】:2013-03-20 14:53:32
【问题描述】:

由于缺少析构函数,我最近遇到了一些错误(bad_alloc)。

我目前有两个班,这样设置的:

class ObjOne {
friend class ObjTwo;
public:                  //constructors and some other random methods
    ObjOne(int n) {
    }

    ObjOne() {
    }

private:
    int currSize;
    int size;
    int *jon;
};


 class ObjTwo {
 public:                       //constructors and some other methods
     ObjTwo(ObjOne, int n) {}  //
     ObjTwo() {}
     ObjTwo(const ObjTwo &source) {    //copy constructor
        num = source.num;
        x = source.x;
        myObjOne=source.myObjOne;
     }
     ~ObjTwo() {                          //destructor
           delete #
           delete &x;
           delete &myObjOne;
      }


private:
    ObjOne myObjOne;
    int num, x;
};

这是我的操作员= ObjTwo

ObjTwo& ObjTwo::operator=(const ObjTwo& other) {
    num = source.num;
    x = source.x;
    myObjOne=source.myObjOne;
    return *this;
}

首先,我的假设是(如果不正确,请更正这些):

ObjOne 不需要析构函数,因为它只是原始类型,编译器何时会使用默认析构函数来清理它。 ObjTwo 确实需要一个析构函数,因为它包含 ObjOne ObjTwo 析构函数需要从 x,num 和 myObjOne 释放内存。

我已经在析构函数上进行了几次尝试,但是我仍然遇到 bad_alloc 错误(在使用巨大循环等进行测试时)或其他错误(当前的错误在调用析构函数时会崩溃)。

感谢任何关于我做错了什么的指导

编辑: 当我简单地将它放在一个循环中时,我抛出了一个 bad_alloc 异常:

ObjTwo b(//some parameters);
ObjTwo a(//some parameters);
for (int i=0; i<20000000; i+) {
    bool x = (a == b);
}

这是重载的 == 运算符

bool ObjTwo::operator==(const ObjTwo& other) {

ObjTwo temp = other;

for(int i=myObjOne.x; i>=0; i--) {
    if(myObjOne.get(i)!=temp.myObjOne.get(i)) {
        return false;
    }
}
return true;
}

在阅读了一些错误之后,它似乎是由于内存不足引起的;我无法正常工作的析构函数会导致。这可能是什么问题?

get 方法只返回 jon[i];

【问题讨论】:

  • 你什么都没有new,没必要delete
  • 你的例子都不正确。你好像有什么误会。如果你的类分配了一些内存,你需要一个析构函数。 ObjTwo 不这样做,也不需要析构函数。 ObjOne 也不在您向我们展示的代码上。但是 ObjOne 中的大红旗是指针。如果 ObjOne 分配了一些内存并使用jon 指向该内存,那么它肯定需要一个析构函数。这就是你应该寻找的,如果你的类包含指针,那么它们很可能需要一个析构函数。
  • 编辑后 - 错误很可能是因为您的内存不足。但是您还没有向我们展示任何分配内存的代码。到目前为止,您向我们展示的只是写得不好的析构函数。发布完整代码。

标签: c++ constructor operator-overloading destructor rule-of-three


【解决方案1】:

您不需要对delete 进行任何使用。您应该 delete 之前使用new 分配的东西。

ObjTwo中,成员myObjOnenumx绝对不应该是deleted。事实上,您永远不应该使用成员的地址和delete。当成员所属的对象被销毁时,成员会自动销毁。

例如,考虑有一个这样定义的成员:

int* p;

这个p 是一个指向int 的指针。当它所属的对象被销毁时,指针本身也将被销毁。然而,想象一下在构造函数中你像这样动态分配一个int 对象:

p = new int();

现在,因为new 动态分配对象,您将需要delete p 指向的对象。您应该使用delete p; 在析构函数中执行此操作。请注意,这不是在破坏p,而是在破坏它指出的对象。由于p 是成员,您不应该手动销毁它。

【讨论】:

  • 这是我的想法;但是,当我一遍又一遍地重复操作而没有'new'或'malloc'时,为什么我会遇到bad_alloc错误。
  • @DaxDurax 它可能来自许多地方。您最好尝试找到bad_alloc 异常的来源。
  • @DaxDurax 例如,将元素插入标准容器可能会导致bad_alloc
  • @DaxDurax 我会回应 sftrabbit 所说的 everything,但补充说您似乎对该语言有一些基本的误解。这不一定是坏事——每个人都曾是初学者,值得称赞的是,你正在努力学习。但重要的是要消除这些误解并正确理解底层概念(例如何时需要析构函数以及应该删除什么和不应该删除什么)。我会强烈建议拿起this book。
  • @DaxDurax 需要明确的是,您是否需要析构函数与类型是否为原始类型完全无关。
【解决方案2】:

ObjOne 可能需要一个析构函数。这不是关于原始类型,而是关于动态分配的内存(指针)之类的东西。你有一个int* 成员,它可能是动态分配的,或者至少是一个指向动态内存的指针。所以你需要在这个上使用deletedelete[]
你在~ObjectTwo 做的事是致命的!您正在尝试从堆栈中删除内存-> 未定义的行为,但大多数情况下会崩溃。你所有的对象/变量都是堆栈分配的,所以你不能删除它们......

【讨论】:

  • No...objOne 可能需要一个析构函数,如果 int* 成员是使用 new 分配的,但这不是设置该成员的唯一方法- 他可以用其他地方的另一个整数的地址来初始化它。在他的情况下,它根本没有分配,所以他不需要析构函数。
  • 我更正了我的帖子,但通常你会有一个指向动态分配内存的指针......从这几行代码中不清楚。
猜你喜欢
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 2016-04-02
  • 2021-06-12
  • 2013-12-14
  • 2013-10-31
相关资源
最近更新 更多