【问题标题】:Problems with pointers in a list列表中的指针问题
【发布时间】:2011-10-18 07:03:30
【问题描述】:

由于某种原因,当我尝试在 std::list (playerlist) 中读取指向对象(GamePlayer) 的指针的属性时,它起初可以工作,但是当我稍后尝试在另一个函数中访问它时我得到一堆随机数,而不是客户端套接字的数字。那是一口,对不起。我希望有人能对这种情况有所了解。我将包含缺陷代码的简化版本。

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

【问题讨论】:

  • 检查你的套接字在你的好读和坏读之间发生了什么。如果您可以取消引用指针,则列表可能没有任何问题。
  • @Roland:这种错误可以通过sscce来诊断。

标签: c++ pointers stl winsock


【解决方案1】:

最可能的解释是您调用addPlayer 时使用的指针在您调用logicPort 时变得无效。一种可能是您调用addPlayer 时使用堆栈上的对象的地址,当堆栈展开时该对象消失。

编辑问题就在这里:

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

PlayerDB::addPlayer 按值获取第二个参数。这意味着它会获得一个在方法的生命周期内存在的副本。然后,您将指针指向该副本,并将其添加到列表中。一旦PlayerDB::addPlayer返回,指针就失效了。

如果不查看更多代码,很难提出好的修复建议。一种可能性是让PlayerDB::addPlayer 将指针作为其第二个参数,并确保您不会在调用链的上一级重复同样的错误

更好的可能性是将playerlist 转换为list&lt;GamePlayer&gt;:从您的代码看来,列表似乎不需要包含指针。这将大大简化事情。

【讨论】:

  • tempplayer.socketno = sid; // 添加一个玩家到房间 roomman.addPlayer( &tempplayer, tempplayer.roomno );
  • @RolandSams:仍然需要更多上下文。堆栈上的对象tempplayer 是什么?
  • 对不起,我是新人,你能告诉我如何在我的回复中格式化代码吗?
  • @RolandSams:您可以使用反引号 (`) 作为短代码 sn-ps。长 sn-ps 最好作为问题的一部分发布(您可以编辑)而不是 cmets。
  • 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 &lt;&lt; "Player name " &lt;&lt; tempplayer.name &lt;&lt; " has logged on" &lt;&lt; endl; return true; }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2020-05-28
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多