析构函数问题

时间:2009-07-04 09:23:08

标签: c++ pointers destructor

这是我的addCard函数,它将一个playCard作为参数,然后将其self的地址移交给一个分配给playCard对象的指针数组。

void cardHand::addCard(playingCard card) {
    theHand[nElems++] = &card;
} // addCard()

现在,当我运行我的程序时,它运行正常,但在调用析构函数时崩溃。

cardHand::~cardHand() {
    for(int c = 0;c<MAX;c++) {
        if(theHand[c] != NULL)
            delete theHand[c]; // here is the problem
    }
    delete [] theHand;
} // class destructor
它是崩溃的因为我只是在addCard函数中移交了playingCard对象的地址。它应该是指针吗?

7 个答案:

答案 0 :(得分:7)

问题出在这里

void cardHand::addCard(playingCard card) { theHand[nElems++] = &card; }

存储将在addCard方法结束时销毁的临时卡对象的地址。

在你的析构函数中,你试图再次删除它。

您有两种选择。

首先:让addCard接受卡片配置,并使用new方法使用addCard创建卡片。
第二:通过指针接受卡,但是您的cardHand的析构函数不能负责删除卡。删除将执行创建所有卡的Deck对象。

答案 1 :(得分:6)

当你说:

theHand[nElems++] = &card;

您正在存储函数参数的地址,该参数实际上是一个局部变量。这总是一件坏事,在您的情况下,当您尝试删除它时会导致崩溃。

您可能需要以下内容:

theHand[nElems++] = new playingcCard( card );

但真正的解决方案是使用playCard的std :: vector并完全取消动态分配。

答案 2 :(得分:4)

你使用C ++作为一个更好的C,虽然这很好用于很多目的但它不是惯用的C ++。

你真正想要的是完全取消动态分配。一般来说,如果你正在编写C ++,你应该很少使用new,甚至更少使用delete

你的手应该被宣布为:

std::vector< playingCard > hand;

应该用这样的东西放上新卡:

hand.push_back( card );

您应该通过使用C ++库的集合类(以及TR1智能指针)来发现,您永远不需要使用newdelete - 直到您无论如何都要编写自己的智能指针。

答案 3 :(得分:1)

它在delete上崩溃,因为它从未与new分配。

void cardHand::addCard(playingCard card) {
    theHand[nElems++] = &card;
} // addCard()

在此函数调用中,您传递的是playCard的临时副本并获取其地址。除非你真的知道自己在做什么,否则存储临时地址是不可能的。

相反,将其更改为

/** @param card card to add. Takes ownership. */
void cardHand::addCard(playingCard *card) {
    theHand[nElems++] = card;
} // addCard()

在调用代码中,传递一个从playingCard返回的new playingCard对象指针。

它仍然存在对象所有权转移的问题,这是双重删除错误或内存泄漏的常见原因。用代码注释明确表达这种转移是一个好习惯。

答案 4 :(得分:1)

所以考虑到其他答案,我的做法是移交引用或指向playingCard的指针。

关于delete,一般规则是,你只deletenew编辑的内容,即分配内存的人应该对其处置负责。 当然,与任何规则一样,也有例外情况,但这种行为需要在接口的合同中很好地记录。

答案 5 :(得分:1)

经验法则:仅删除您分配的内容(使用new或使用malloc)

因此,你的崩溃。

答案 6 :(得分:1)

它不起作用的原因是你在cardHand::addCard中按价值传递了你的课程 因此,编译器所做的是在堆栈上构造类实例的临时副本 当它在堆栈中时,一旦addCard函数返回,它将自动清理 您可以通过将playingCard实例作为指针传递来解决此问题 但是,正如本文中的其他人所说,建议不要delete你没有明确new的内容。