1

我是 C++ 新手。我确实试图在我得到的书籍上找到答案并在谷歌上搜索,但找不到问题根源的线索。

这可能是一件非常愚蠢的事情。希望有人能在这里阐明一下我在下面复制所有内容:

当我使用 myHand.Add(pCard1) 时,Hand::ShowHand2 仅以某种方式与“myHand.Add(pCard2)”一起使用,但出现以下错误:

*** glibc detected *** /home/remy/workspace-C/myPoker/Debug/myPoker: double free or corruption (out): 0x00007fff7723d2d0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fef4fd1bb96]
/home/remy/workspace-C/myPoker/Debug/myPoker[0x401869]
/home/remy/workspace-C/myPoker/Debug/myPoker[0x40172c]
/home/remy/workspace-C/myPoker/Debug/myPoker[0x401b41]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fef4fcbe76d]
/home/remy/workspace-C/myPoker/Debug/myPoker[0x400e19]
======= Memory map: ========
00400000-00404000 r-xp 00000000 07:00 875533                             /home/remy/workspace-C/myPoker/Debug/myPoker
00603000-00604000 r--p 00003000 07:00 875533                             /home/remy/workspace-C/myPoker/Debug/myPoker
00604000-00605000 rw-p 00004000 07:00 875533                             /home/remy/workspace-C/myPoker/Debug/myPoker
02534000-02555000 rw-p 00000000 00:00 0                                  [heap]

这是完整的代码:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Card
{
public:
    enum rank {ace = 1, two, three, four, five, six , seven, eight, nine, ten, jack, queen, king};
    enum suit {club =1 , diamonds, hearts, spades};
    friend ostream& operator    <<  (ostream& os,  Card& aCard);

    Card(rank r = ace, suit s = spades);
    rank m_rank;
    suit m_suit;

};

Card::Card(rank r, suit s){
    m_rank =    r;
    m_suit  =   s;
}

ostream& operator<<(ostream& os,  Card& aCard)
{
    const string RANKS[] = {"0", "A", "2", "3", "4", "5", "6", "7", "8", "9",
                        "10", "J", "Q", "K"};
    const string SUITS[] = {"c", "d", "h", "s"};
    os << RANKS[aCard.m_rank] << SUITS[aCard.m_suit];

    return os;
}

class Hand
{
    public:
    Hand();
    virtual ~Hand();

void Add(Card* pCard);
void Clear();
void ShowHand();
void ShowHand2();

    protected:
    vector<Card*> m_Cards;

};

Hand::Hand(){
    cout    << "hand is created "   << endl;
    m_Cards.reserve(7);
}
Hand::~Hand()
{
    Clear();
}

void Hand::Add(Card* pCard)
{
    cout    <<  "*pCard: "  <<  *pCard  << " is @: "    <<  pCard   <<  endl;
    m_Cards.push_back(pCard);
}

void Hand::Clear(){
    vector<Card*>::iterator iter = m_Cards.begin();
    for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
    {
    delete *iter;
    *iter   =   0;
    }
    m_Cards.clear();
}


void Hand::ShowHand(){

        int k = 1;
        vector<Card*>::iterator iter = m_Cards.begin();
    for (iter = m_Cards.begin() ; iter != m_Cards.end(); ++iter, ++k)
    {
        cout    << "card no "   <<  k   << " is: ";
        cout    <<  **iter  << endl ;
    }

}


void Hand::ShowHand2(){

        vector<Card*>::iterator iter = m_Cards.begin();
        cout << "this hand has "    <<  m_Cards.size()  << " card(s)."<< endl;

        for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
{
    cout    << **iter   <<  endl;
}
}



int main(){

Card c1(static_cast<Card::rank>(11), static_cast<Card::suit>(0));

Card*   pCard1  =   &c1;
Card*   pCard2;
pCard2  =   new Card(static_cast<Card::rank>(12), static_cast<Card::suit>(0));

Hand myHand;

myHand.Add(pCard1);
//  myHand.Add(pCard2);

//  myHand.ShowHand();
myHand.ShowHand2();

cout    <<  "End of Program"    <<  endl;


return 0;
}

提前非常感谢!

4

2 回答 2

3

您添加pCard1到您的手,这是一个指向将自动销毁的局部变量的指针。但是,您~Hand()将调用delete它分配的所有卡片。在那里你有你的双倍免费。

如果您使用pCard2您分配的Card实例 vianew并因此负责在其上调用 delete。

正如您在评论中看到的那样,您应该考虑使用智能指针来避免此类问题。

编辑 更详细地解释您的主要问题:您使用指向由编译器自动管理的局部变量的指针。但是,然后您将add()它交给拥有指向对象所有权的手,因为当手本身被破坏时,它将删除它。这基本上导致同一对象有两个所有者。

通过 new 生成实例,没有所有者负责销毁。但是,当您将其添加到手牌时,手牌将拥有它并将其删除。

于 2013-06-22T18:39:26.993 回答
1

让我们采取这个:

enum suit {club =1 , diamonds, hearts, spades};

在这里你宣布club存在1diamonds存在2`hearts存在3spades存在4

然后你有这个数组

const string SUITS[] = {"c", "d", "h", "s"};

你用suit.

但是,数组的索引从零开始,这意味着spade您的索引超出了数组的范围,并在您使用 at 的“字符串”时进入未定义行为SUITS[4]的领域。

于 2013-06-22T18:39:47.067 回答