C++ 析构函数,动态分配

C++ Destructors , dynamic allocation

提问人:Dax Durax 提问时间:3/30/2013 最后编辑:Dax Durax 更新时间:3/30/2013 访问量:5251

问:

由于缺少析构函数,我最近遇到了一些错误(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 Destructor 需要从 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];

C++ 造函数 运算符重载 析构函数 三法则

评论

0赞 Simon G. 3/30/2013
你什么都没做,没必要.newdelete
1赞 john 3/30/2013
你的例子都不正确。你似乎有些误会。如果你的类分配了一些内存,则需要一个析构函数。ObjTwo 不这样做,也不需要析构函数。ObjOne 也没有使用您向我们展示的代码。但 ObjOne 中的大红旗是指针。如果 ObjOne 分配了一些内存并用于指向该内存,那么它肯定需要一个析构函数。你应该寻找的是,如果你的类包含指针,那么它们很可能需要一个析构函数。jon
0赞 john 3/30/2013
编辑后 - 错误很可能是因为内存不足。但是您还没有向我们展示任何分配内存的代码。到目前为止,您向我们展示的都是写得不好的析构函数。发布完整的代码。

答:

2赞 Joseph Mansfield 3/30/2013 #1

您不需要对 进行任何使用。您应该使用之前分配过 .deletedeletenew

在 中,成员 、 和 绝对不应该是 d。事实上,你永远不应该拿走一个成员的地址和它。当成员所属的对象被销毁时,成员将自动销毁。ObjTwomyObjOnenumxdeletedelete

例如,考虑有一个成员,其定义如下:

int* p;

这是指向 的指针。当指针所属的对象被销毁时,指针本身将被销毁。但是,想象一下,在构造函数中,您动态分配一个对象,如下所示:pintint

p = new int();

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

评论

0赞 Dax Durax 3/30/2013
这就是我的想法;但是,当我一遍又一遍地重复操作而没有“new”或“malloc”时,为什么我会遇到bad_alloc错误。
0赞 Joseph Mansfield 3/30/2013
@DaxDurax 它可能来自多个地方。最好尝试找到异常的来源。bad_alloc
0赞 Joseph Mansfield 3/30/2013
@DaxDurax 例如,将元素插入到标准容器中可能会导致 .bad_alloc
0赞 Nik Bougalis 3/30/2013
@DaxDurax 我会回应 sftrabbit 所说的一切,但补充一点,你似乎对这门语言有一些根本性的误解。这不一定是坏事——每个人都是初学者,值得称赞的是,你正在努力学习。但重要的是要消除这些误解并正确理解基本概念(例如何时需要析构函数以及应该删除和不应该删除的内容)。我强烈建议你拿起这本书
1赞 Joseph Mansfield 3/30/2013
@DaxDurax 需要明确的是,是否需要析构函数与类型是否为原始类型完全无关。
1赞 bash.d 3/30/2013 #2

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

评论

0赞 Nik Bougalis 3/30/2013
不。。。 可能需要一个析构函数,如果成员是使用 分配的,但这不是设置该成员的唯一方法 - 他可以使用来自其他地方的另一个整数的地址初始化它。在他的情况下,它根本没有分配,所以他不需要析构函数。objOneint*new
0赞 bash.d 3/30/2013
我更正了我的帖子,但通常你会有一个指向动态分配内存的指针......从这几行代码中看不出来。