   Very confusing, possibly multi-threading related problem.
  First of all: I am using directplay and have told it not to start any new threads, so I do not think that multiple threads are the issue here.  However, I'm so confused I thought that that might be it, so I even tried using windows' mutex objects, but they didn't help either (the mutex wait/signal functions report they are working properly, but the problem persists).The problem is this:  I am writing a server.  The server has a list of objects it should broadcast to all of the connected players every 10 milliseconds.  When a player connects, he gets his own object in this list, and when he disconnects, the object is destroyed.  It all works fine about half of the time.The other half of the time, even after the player object is destroyed, the function that broadcasts the position of all the objects behaves as if the object were NOT removed.  It accesses the pointer to the object, which is of course no longer valid, and crashes the program.Here is the relevant code.  This gets called when the player disconnects:  std::cout << "DISCONNECT RECEIVED FROM " << ((CLIENT *)playerContext)->name << std::endl;if (((CLIENT *)playerContext)->playerObjectPointer != NULL){std::cout << "REMOVING PLAYER\n" << std::flush;removePlayer(((CLIENT *)playerContext)->playerObjectPointer);}and this is the broadcast function: std::cout << "objects.size() = " << objects.size() << std::endl << std::flush;int size = objects.size();for (i = objects.begin(); i != objects.end(); i++){std::cout << "SL:DKFJSDL:FJ\n" << std::flush;(*i)->getPos(msg.posX, msg.posY, msg.posZ);(*i)->getVel(msg.velX, msg.velY, msg.velZ);(*i)->getAngP(msg.angPX, msg.angPY, msg.angPZ);msg.playerID = (*i)->id;server->sendToAll(&msg, sizeof(msg));}Now, for the strange output when it crashes:...objects.size() = 0objects.size() = 0objects.size() = 0CONNECTION REQUEST RECEIVED. name: rileyCREATING PLAYER OBJECTobjects.size() = 1SL:DKFJSDL:FJobjects.size() = 1SL:DKFJSDL:FJobjects.size() = 1SL:DKFJSDL:FJDISCONNECT RECEIVED FROM rileyREMOVING PLAYERIN removeObject: objects.size() is now 0SL:DKFJSDL:FJ<crash, bad pointer>When it goes well, the end of the output is:DISCONNECT RECEIVED FROM rileyREMOVING PLAYERIN removeObject: objects.size() is now 0objects.size() = 0objects.size() = 0objects.size() = 0...<continued normal operation; I can connect again, try my luck at disconnecting again, etc>When it crashes with the bad pointer, the value of objects.size() is reported as 1, AFTER the removeObject function said that objects.size() was now 0.  Furthermore, notice that the broadcastState function does NOT print the objects.size() line at all when it crashes.  It prints the SL:DKFJSDL:FJ line twice in a row, even though at no point is objects.size() > 1, and at no point is removeObject called in that loop anyway.I am so  confused.  If anyone has any ideas at all about what could cause this, I would appreciate it.  I've been just staring at this problem for the last two days.Thanks for any help,Riley[edited by - rileyriley on February 16, 2004 8:59:32 PM]
  I have no idea if this is right or not, but...what if, for some bizarre reason, objects.end() were returning not an interator pointing to the location after the last element (== first if no elements), but a pointer to the end of the vector''s storage buffer? (which has been grown by one but, I think, doesn''t automatically shrink again)ie. temporarily replace ''i != objects.end()'' with ''i != objects.start()+objects.size()'' and see what happens? ;  Thanks for the idea, I thought of that too.  The problem is that objects.size() == 1 in the function!  Argh!  So objects.begin() + objects.size() will still be an invalid pointer, even if this weird objects.end() bug were happening. ;  some further information:1: the iterator i is "fine," in so far as the debugger seems to think it's a valid iterator.  I can look at the different members of i, etc.  It's the pointer that (*i) holds that is bad.2: the crash happens on the (*i)->getPos() call.  edit: well, every time so far it has.Thanks again for any thoughts.  I'm literally squirming in my chair over this  [edited by - rileyriley on February 16, 2004 9:26:37 PM];  OK... erk. This sounds confusing... basically I''m trying to figure out all the assumptions I would have made in your place, and then test them, because one of them is gotta be wrong.You aren''t doing something obvious like passing the objects vector by value not reference at some stage? *scrapes bottom of barrel* ;  I never pass it, it''s a member variable, and all of these functions are member functions.  Good idea, though, that certainly could mess stuff up...I''m gonna go walk around the block.  Or the county, you know, whichever.  Thanks for the help.. keep it coming! ;  Do you remove the actual entry from the std::vector / std::list that you''re using?For example:delete (*VectorIterator);(*VectorIterator) = NULL;Doesn''t remove the entry from the list, just the data that the itererator is pointing too.  You need to do an .erase on the vector / list. ;  Do you set the pointer to NULL when you delete it? If so, and it''s non-null again by the time that it gets to the broadcast function, then obviously either you''re somehow writing to the wrong vector, or it''s being changed back.Try printing out &objects and this in both removeObject() and broadcast(), and see if they''re the same both places? ;quote:Original post by GroZZleR  ...Doesn''t remove the entry from the list, just the data that the itererator is pointing too.  You need to do an .erase on the vector / list.   Yeah, I find() to get the iterator, then objects.erase(it).  If I didn''t, I would think this would crash every time, not just half the time.;quote:Original post by fractoid   Do you set the pointer to NULL when you delete it? If so, and it's non-null again by the time that it gets to the broadcast function, then obviously either you're somehow writing to the wrong vector, or it's being changed back.Try printing out &objects and this in both removeObject() and broadcast(), and see if they're the same both places?   I did try setting the pointer to NULL after deleting it.  The change was not evident in broadcastState().  This is another symptom that makes me think this is actually running in multiple threads.Added some more debug output.  Now, crash end:DISCONNECT RECEIVED FROM rileyREMOVING PLAYERremoving object.removed object.Here, objects.size() = 0in removeObject:  this: 00981230  &objects: 00981240in broadcastState();  this: 00981230  &objects: 00981240SL:DKFJSDL:FJ [edited by - rileyriley on February 16, 2004 10:13:05 PM]