#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; }