Проблемы с указателями в списке

#c #pointers #stl #winsock

#c #указатели #stl #winsock

Вопрос:

По какой-то причине, когда я пытаюсь прочитать свойство указателя на объект ( GamePlayer ) внутри std::list ( playerlist ), сначала это работает, но когда я пытаюсь получить к нему доступ позже в другой функции, я получаю кучу случайных чисел вместо чисел для сокета моего клиента. Это был полный бред, извините. Я надеюсь, что кто-нибудь мог бы пролить некоторый свет на ситуацию. Я включу упрощенную версию дефектного кода.

 class GameRoom  {

    list<GamePlayer*> playerlist;
    locigPort( LogicObj );
}


bool GameRoom::logicPort( LogicObj logit )  {   // This is room[1]

    list<GamePlayer*>::iterator it;

        for (it = playerlist.begin(); it != playerlist.end(); it  ){  

                cout << "socket numbers " << (*it)->socketno << endl;  
                /* (*it)->socketno gives me a bunch of random numbers, 
                   not the socket numbers I was looking for! */
        }  

    return true;

}

bool RoomDB::addPlayer( GamePlayer *playerpoint )   {

    roomlist[1].playerlist.push_back( playerpoint );    
    // This adds the player object to the Gameroom object

    cout << "player point " << playerpoint->socketno << " roomno: " << roomno;  
    // This shows everything should be ok so far

    return true;
}
  

Комментарии:

1. Проверьте, что происходит с вашими сокетами между вашим хорошим чтением и плохим чтением. Если вы можете разыменовать указатель, вероятно, со списком все в порядке.

2. @Roland: Такого рода ошибки могут быть диагностированы с помощью sscce .

Ответ №1:

Наиболее вероятное объяснение заключается в том, что вы вызываете addPlayer с помощью указателя, который к моменту вызова становится недействительным logicPort . Одна из возможностей заключается в том, что вы вызываете addPlayer с адресом объекта в стеке, и объект исчезает, когда стек разматывается.

редактировать Проблема прямо здесь:

 bool PlayerDB::addPlayer( int sid, GamePlayer tempplayer ) {
   ...
   roomman.addPlayer( amp;tempplayer, tempplayer.roomno );
}
  

PlayerDB::addPlayer принимает второй аргумент по значению. Это означает, что он получает копию, которая существует в течение всего срока службы метода. Затем вы указываете на эту копию и добавляете ее в список. Как только PlayerDB::addPlayer возвращается, указатель становится недействительным.

Трудно предложить хорошее исправление, не увидев больше кода. Одна из возможностей состоит в том, чтобы заставить PlayerDB::addPlayer принимать указатель в качестве второго аргумента и убедиться, что вы не повторяете ту же ошибку на один уровень выше по цепочке вызовов.

Еще лучшая возможность — включить playerlist в list<GamePlayer> : из вашего кода, похоже, нет никакой необходимости в том, чтобы список содержал указатели. Это значительно упростит работу.

Комментарии:

1. tempplayer.socketno = sid; // Добавить игрока в комнату roomman.addPlayer( amp;tempplayer, tempplayer.roomno );

2. @RolandSams: Все еще нужно больше контекста. Что такое tempplayer объект в стеке?

3. извините, я новичок, можете ли вы сказать мне, как форматировать код в моих ответах?

4. @RolandSams: Вы можете использовать обратные ссылки ( ` ) для коротких фрагментов кода. Длинные фрагменты лучше размещать как часть вашего вопроса (который вы можете редактировать), а не комментарии.

5. bool PlayerDB::addPlayer( int sid, GamePlayer tempplayer ) { tempplayer.socketno = sid; PlayerDBint[sid] = tempplayer; // Add a player to the room roomman.addPlayer( amp;tempplayer, tempplayer.roomno ); cout << "Player name " << tempplayer.name << " has logged on" << endl; return true; }