Jump to content
  • Advertisement
Sign in to follow this  
Ezbez

problems remove()ing with std::list

This topic is 4422 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

To start off, I will describe what I am doing a bit. It may seem a bit irrelevant at the moment, but it might clarify things a bit later. I am using MSVC++ 2005 EE to create a GUI system. I have a Window class which is a standard widget/window/whatever you want to call it. A Window can have child Windows (and, hence, a parent Window). I use an std::list to keep track of which Windows are children of a Window, and a pointer to the parent Window of the Window. Now, when a Window is given input focus, it has the parent Window remove it from the list of child Windows and then add it again. My problem is with the removing of the Window from the child Windows list. I use this function:
void Window::RemoveChild(Window *removedChild)
{
	//childWindows is the std::list
	childWindows.remove(removedChild);
}
However, my program crashes on this line, inside of the remove() call. I get an error message of "list incrementor not incrementable" on line 236 of the list header. Now, this makes me think that removedChild isn't actually inside of remove(). But, I've looked through my code and I can't see how it could not be in there. See, the only way that a child Window can get focus is from a parent Window giving it focus. The only way that RemoveChild() is callled is form a child Window (*parentWindow is checked to be != NULL and I set parentWindow to NULL in the constructor), and it is passed this, so it's not getting the wrong pointer. I've also tried std::find() then erase()ing the found iterator, and writing my own finding algorithm. All of these get the same error that a list iterator cannot be incremented. Well, any suggestions? I don't really know what other code I could possibly show you, since it all _seems_ to be in order. Thanks in advanced.

Share this post


Link to post
Share on other sites
Advertisement
Quite posibly, the childWindows list most likely has become corrupted. This can happen if you either:
Write out out bounds from some array, or
You have multiple threads modifying this list, without explicit locking around use of the list.
I'm picking the later of these...

Share this post


Link to post
Share on other sites
I only have a single thread running on this program.

As for corrupted, I don't think that that is likely. I use the list in other places(eg: telling the parent window to draw makes it have all the child windows draw, too), and it works there. All that I do to the list is iterate through it for drawing and input handling (should probably use for_each()), push_back() new Windows, and remove() in this problem. I don't use any arrays in my program right now (all strings, lists, or vectors), so writing out of bounds shouldn't be a problem. Is there any way to check for corruption?

I know that iterators can become invalid when you remove it from the list. Could this be a problem? Again, I doubt that it is, seeing as Microsoft almost definately got their remove() implementation correct.

[Edited by - Ezbez on July 6, 2006 4:40:19 AM]

Share this post


Link to post
Share on other sites
Try doing ++childWindows.begin() in debug mode and see what it does, I suspect it'll do the same thing. Then take a look at the values of childWindows._Myhead and childWindows._Myhead->_Next in the debugger. The only times this should happen without any form of corruption would be if you were trying to increment an empty or end iterator, which can't happen inside remove().

Share this post


Link to post
Share on other sites
++childWindows.begin() doesn't cause a crash or error or anything. I don't do anything with this iterator other than increment it; would the problem not show up if I don't do something with the iterator?

And, odly enough, it increments fine even if there is only one child window.

Share this post


Link to post
Share on other sites
Try:


list<Window*>::iterator i = childWindows.begin();

while (i != childWindows.end()
{
if (*i == removeChild)
i = childWindows.erase(i);
else
++i;
}


And see what happens

Share this post


Link to post
Share on other sites
Quote:
Original post by Ezbez
++childWindows.begin() doesn't cause a crash or error or anything. I don't do anything with this iterator other than increment it; would the problem not show up if I don't do something with the iterator?

And, odly enough, it increments fine even if there is only one child window.


Hmm, what's the value of _Myhead? Are you able to follow the _Next pointers in the list nodes using the debugger, and do they contain the correct number of nodes and generally seem to make sense? Since you seem to be dealing with raw pointers you should double check that you haven't accidentally deleted the current this pointer somewhere. Something like this for example:

Window* window = new Window();
//...
if(window->closed()) delete window;
//...
window->RemoveChild(child);

It could produce all manner of strange results and could even manifest itself differently with different build configurations. Your description of the process in which this is happenning sounds a bit strange aswell. Why would you remove a child from it's parent and then re-add it when focus changes?

Share this post


Link to post
Share on other sites
I remove it then re-add it so that it is at the back of the list and is drawn last, and hence is on top. This was the way that an article about GUIs in DirectX on this website said to do it.

Unfortunately, I'm not really able to debug it. If I try to debug it, it exits before anything happens, and doesn't tell me anything about why. It runs fine without debugging.

I sure hope that I'm not deleting my childWindows. They are on the stack (yes, I know, it shouldn't be that way). I declare both the child and its parent in the main() function, so they should get removed at the same time.

@Owl - This is almost identical to what I tried originally. It crashes, too, with a "list iterator cannot be incremented" error.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ezbez
Unfortunately, I'm not really able to debug it. If I try to debug it, it exits before anything happens, and doesn't tell me anything about why. It runs fine without debugging.


If I was you I'd be sorting this problem out first. It may be a sign that bad things are happenning else and has nothing to do with your Window class. And even if it's not related, debugging without a debugger really sucks.

Quote:
I sure hope that I'm not deleting my childWindows. They are on the stack (yes, I know, it shouldn't be that way). I declare both the child and its parent in the main() function, so they should get removed at the same time.


BAD MONKEY!!!! Ahem....try commenting out the offending line(s) of code so that your program can run to completion and see if VS complains about the stack being corrupt or anything similarly nasty (ie. check if you've done bad things to your Window instances while they're on the stack).

Share this post


Link to post
Share on other sites
I'm sorry, but I don't quite understand what you mean. Which lines in particular would be the "offending" ones? The declarations of my Windows? Adding the child Windows to the parent Windows? I will test out using new on my Windows, though.

And I'm sorta sure that my problem with debugging comes from using SDL. Would I need to use a special debugging library instead of the typical SDL library?

Edit: some of my debugger output is:

"'OpenGLApplication.exe': Loaded 'C:\Documents and Settings\Owner\Desktop\Tom's Useless Junk\OpenGL Games\Gravitas\Debug\SDL.dll', Binary was not built with debug information."

Along with listing that a bunch of libraries have no symbols loaded (eg: glu32,ntdll, msvcrt, ddraw, many more).

Edit again: Using new for the Windows doesn't change a think, at least as far as I can tell.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!