-1
int main() {

    one.print(two, three);
        cout << "HERE" << endl;
    calculate(3, 1, 2, 3);
    one.~tower();
    two.~tower();
    three.~tower();
    system("PAUSE");
    return 0;
}

大家好。我正在制作一个程序(在 C++ 中),它打印出河内塔谜题的解决方案。所以我有一个叫做 print 的函数,它工作得很好,但是由于某种原因它之后没有返回到 main() 。

所以one.print(two, three)在 main 中没有进一步的命令被执行之后。我知道是因为我用cout. 但是,函数中的所有命令都可以完美执行。这是功能。

void tower::print(tower two, tower three) {

for(int i = 0; i < no; i++) {
    checkandprint(levels[i], no);
    checkandprint(two.levels[i], no);
    checkandprint(three.levels[i], no);
    cout << endl;   
}

for(int i = 0; i < 3; i++) {
    bottoms(no);
}
cout << "Press enter to continue...";
cin.get();
cout << "here (end of function)" << endl;
}

这是该类中该函数的原型tower

class tower {
public:
    int no;
    int *levels;
    tower(int init, bool source);
    ~tower() {int *r = &no; delete r; delete [] levels;}
    void print(tower two, tower three); //this one!
    void bottoms(int rows);
    void assign(int n);
    void move(int dest);

};

有任何想法吗?

4

1 回答 1

1
~tower() {
    int *r = &no; delete r; // <- this is wrong
    delete [] levels;
}

你没有为 分配单独的空间int no,所以你不应该删除它。它的内存包含在tower对象本身的内存中,释放时它会被tower释放,你不必担心。

print函数返回时,这两个tower对象将被销毁并调用它们的析构函数twothree当他们试图删除no他们没有分配的指向 的指针时,您的程序将产生未定义的行为,这意味着此时任何事情都可能发生。幸运的是,发生在你身上的只是程序崩溃了,但我看到更糟糕的事情发生了...... http://xkcd.com/292/

另请注意,您的析构函数可能仍然存在其他问题,具体取决于您分配和/或复制levels数组的方式,特别是在将tower值传递给print. 您最好使用 astd::vector<int> levels代替,然后您不必担心分配或删除它。

哦,是的,就像评论中提到的人一样,你不要这样做:

one.~tower(); // bad, very very bad and wrong,
              // just wrong, bad and wrong, and awful, just...
              // just don't do it, ok?

当对象被销毁时,程序会调用析构函数:当您明确delete分配自己分配的对象时,或者当对象的生命周期结束时,例如当函数返回并且所有本地对象都被销毁时(这就是发生在print,tower twotower three, whenprint返回的参数)。

于 2013-07-19T20:21:54.760 回答