valgrind中的一些错误

时间:2016-12-02 23:34:01

标签: c++ valgrind destructor

我已经设法使用本指南解决了这个问题:https://web.stanford.edu/class/cs107/guide_valgrind.html

这是我要求使用valgrind和cpp的第一个项目。 我在valgrind中遇到一些我无法解决的错误。 所以第一个就是这个:

==2788==  Block was alloc'd at
==2788==    at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2788==    by 0x408F33: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >::allocate(unsigned long, void const*) (new_allocator.h:104)
==2788==    by 0x408ADB: std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >&, unsigned long) (alloc_traits.h:491)
==2788==    by 0x40829C: std::_Rb_tree<int, std::pair<int const, std::vector<Card*, std::allocator<Card*> > >, std::_Select1st<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >::_M_get_node() (stl_tree.h:491)
==2788==    by 0x407360: std::_Rb_tree_node<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >* std::_Rb_tree<int, std::pair<int const, std::vector<Card*, std::allocator<Card*> > >, std::_Select1st<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<int const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<int const&>&&, std::tuple<>&&) (stl_tree.h:545)
==2788==    by 0x4068E8: std::_Rb_tree_iterator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > std::_Rb_tree<int, std::pair<int const, std::vector<Card*, std::allocator<Card*> > >, std::_Select1st<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<int const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >, std::piecewise_construct_t const&, std::tuple<int const&>&&, std::tuple<>&&) (stl_tree.h:2170)
==2788==    by 0x406052: std::map<int, std::vector<Card*, std::allocator<Card*> >, std::less<int>, std::allocator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > > >::operator[](int const&) (stl_map.h:483)
==2788==    by 0x4054A5: Hand::addCard(Card&) (Hand.cpp:186)
==2788==    by 0x409760: Player::addCard(Card&) (Player.cpp:17)
==2788==    by 0x40B9F5: Game::init() (Game.cpp:175)
==2788==    by 0x40ECDB: main (reviiyot.cpp:17)

现在这里的相关代码如下所示。这个函数应该给一张牌添加一张牌,这张牌是一张带钥匙的地图和一张指向Card对象的指针。

bool Hand::addCard(Card &card){
    int key=getKey(card);
    vector<Card*>::iterator it_vec;
    map <int,vector<Card*>>::iterator it=hand.find(key);
    if(it!=hand.end()){ // found in hand
        for (it_vec=it->second.begin();it_vec!=it->second.end();it_vec++){
            if (card.getShape()<(*it_vec)->getShape()){
                hand[key].insert(it_vec,&card);
                break;
            }
        }
        if(it_vec==it->second.end()){
            hand[key].push_back(&card);
        }
    }
    else {
        hand[key]={};
        hand[key].push_back(&card);// erorr line
    }
    return true;
}

现在该项目正在运行并且没有泄漏,但是valgrind似乎并不喜欢插入尚未出现的卡片。我认为它是语法的东西,但我尝试了不同的方法来做到这一点,它没有工作。我试图使用插入对,并交换矢量。似乎没有用。

这是另一个错误:

==2788== 214 errors in context 5 of 5:
==2788== Invalid read of size 8
==2788==    at 0x405EAC: std::vector<Card*, std::allocator<Card*> >::clear() (stl_vector.h:1212)
==2788==    by 0x40C02D: Game::play() (Game.cpp:271)
==2788==    by 0x40ED00: main (reviiyot.cpp:20)

这是游戏中的代码(我标记了这一行):

void Game:: play(){

    Card* curr_card;
    int curr_tact;
    unsigned int i=0;
    string card_first="";
    vector<Card*>::iterator iter;
    int curr_que;
    int num_from_type;
    bool que;
    int win_que=-1;
    int win_asker=-1;
    vector<Card*>* card2pass;

    for( i=0; i<players.size(); i++){

        curr_card=players.at(i)->strategy();
        curr_tact=players.at(i)->getTactic();
        switch (curr_tact){
        case (1):{
            curr_que=most_cards(i);
        }break;
        case (2):{
            curr_que=most_cards(i);
        }break;
        case (3):{
            curr_que=players.at(i)->get_curr_que();
        }break;
        case (4):{
            curr_que=players.at(i)->get_curr_que();
        }break;
        }
        card_first=curr_card->toString().at(0);
        if (verbal_on==1){
            cout <<"Turn " << turn <<endl;
            printState();
            cout<<players.at(i)->getName()+" asked "+players.at(curr_que)->getName()+" for the value "+card_first << endl <<endl;
        }
        //here comes the play:
        que=players.at(curr_que)->search(*curr_card);
        // complete else of this if
        if(que==true){
            //instead this vec take from players hand
            card2pass=players.at(curr_que)->get_cards(*curr_card);
            num_from_type=card2pass->size();
            players.at(i)->recive(*card2pass);
            players.at(curr_que)->removeCard(*curr_card);
            // has asker completed a set
            completed_set(*curr_card,i);

            card2pass->clear(); // error line
            // the code continues here.. 

我在card2pass中使用了clear()函数,所以我可以在下一次迭代中使用它。但由于某些原因,valgrind不喜欢它。显然我不想删除卡片,因为我希望其他玩家获得卡片以便他们可以指向它。    最后一个就是这个:

 **

==2788== 133 errors in context 2 of 5:
==2788== Invalid read of size 8
==2788==    at 0x4EDEA60: std::_Rb_tree_increment(std::_Rb_tree_node_base const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==2788==    by 0x405DE7: std::_Rb_tree_iterator<std::pair<int const, std::vector<Card*, std::allocator<Card*> > > >::operator++(int) (stl_tree.h:213)
==2788==    by 0x404D8D: Hand::~Hand() (Hand.cpp:82)
==2788==    by 0x4096FF: Player::~Player() (Player.cpp:14)
==2788==    by 0x409AED: PlayerType1::~PlayerType1() (Player.cpp:61)
==2788==    by 0x409B1D: PlayerType1::~PlayerType1() (Player.cpp:62)
==2788==    by 0x40A8EB: Game::~Game() (Game.cpp:31)
==2788==    by 0x40EDC9: main (reviiyot.cpp:19)

所以Game有这些参数:

class Game {
private:
    vector<Player*> players;  //The list of the players
    Deck deck;                 //The deck of the game
    string winners;         //String representing the winners
    int verbal_on;          // printing command
    int turn;               // counts the number of turns 

游戏的析构函数:

Game:: ~Game(){
    unsigned int i;
    if(players.size()!=0){
        for(i=0;i<players.size();i++){
                delete players[i];
           }
       }
}

玩家的析构函数为空,(playerType1扩展Player扩展抽象类Hand),Hands析构函数为:

Hand:: ~Hand(){
    map <int,vector<Card*>>::iterator it_map;
    unsigned int it_vec;
    for (it_map = hand.begin(); it_map != hand.end(); it_map++){//error line
        for (it_vec = 0; it_vec < (it_map->second).size(); it_vec++){
            delete (it_map->second).at(it_vec);
        }hand.erase(it_map);
    }
}

我想迭代器有一些问题,但我不明白它是什么。

1 个答案:

答案 0 :(得分:1)

map <int,vector<Card*>>
bool Hand::addCard(Card &card)
hand[key].push_back(&card)

你使用带有'指针卡'的地图。但是传递一个引用(Card&amp;)和push_back该引用的地址。

尝试

map <int,vector<Card*>>
bool Hand::addCard(Card* card)
hand[key].push_back(card)

map <int,vector<Card>>
bool Hand::addCard(Card &card)
hand[key].push_back(card)