Skip to main content
gamedev.net
🔒 Locked

List problems

Started by EmrldDrgn 17 replies 2.2k views
Original Post
EmrldDrgn
EmrldDrgn
I am, for some reason, getting an error when I use list.end();. It doesn't show up at compile time, but throws an unhandled exception at runtime. I'll show you the code for my list declaration, but it really doesn't make much sense to me that something as well-documented as the STL would throw random exceptions all over the place.

list<npc_object>* CurrentNPCs = new list<npc_object>;

There's the declaration. If I change it back from new, the error is still there, so that's not it. What's the problem there?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
dave
dave
With all due respect if the error is not with the instantiation of the list then why did you paste it? [grin]

Paste the usage of that list please.

Dave
Anatol
Anatol
With the provided information, this is just a wild guess, but are you maybe dereferencing end() ? AFAIK, the iterator returned actually points one element past the end of the list. Someone please correct me if I'm wrong.
deathkrush
deathkrush
Quote:
Original post by Anatol
With the provided information, this is just a wild guess, but are you maybe dereferencing end() ? AFAIK, the iterator returned actually points one element past the end of the list. Someone please correct me if I'm wrong.


Yes, it points to one element past the end of the list. Dereferencing .end() would be like dereferencing a null pointer.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
iMalc
iMalc
Quote:
Original post by deathkrush
Quote:
Original post by Anatol
With the provided information, this is just a wild guess, but are you maybe dereferencing end() ? AFAIK, the iterator returned actually points one element past the end of the list. Someone please correct me if I'm wrong.


Yes, it points to one element past the end of the list. Dereferencing .end() would be like dereferencing a null pointer.
Yeah pretty much.
If you actually want an iterator pointing to the last element in the list, use:
CurrentNPCs.rbegin()
Just make sure that you already know that the list isn't empty, or check the resulting iterator against CurrentNPCs.rend() before using it.
EmrldDrgn
EmrldDrgn
The usage of the list is just CurrentPCs.end(). I'm not dereferencing it at all. However, my list might be empty... is that likely to cause a problem?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
CoyCash
CoyCash
It doesn't matter if the list is empty. Something like this works fine:
list<int> *l = new list<int>;l->end();
Conner McCloud
Conner McCloud
Without code, everybody's just going to be taking wild stabs in the dark. Provide the actual code that causes the problem, and the specific error you recieve, and we can actually start making educated statements.

CM
Zahlman
Zahlman
Why not show the actual code that causes the problem, like the first responder suggested?
EmrldDrgn
EmrldDrgn
All right, here is the code which causes the error.

PCs_iterator = CurrentPCs->begin();while(1){	PCs_iterator++;	if (PCs_iterator == CurrentPCs->end())		break;        (*(PCs_iterator)).Update();}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
dominicoder
dominicoder
If your list is empty, I believe (not positive) that begin() is equal to end(), so when you start your loop and immediately increment your iterator, you will go past end(), to garbage. Your equality check will fail and your code will try to call update on the iterator, which will explode.

Try this:
for (PCs_iterator = CurrentPCs->begin(); PCs_iterator != CurrentPCs->end(); ++PCs_iterator)PCs_iterator->Update();
HQ-SOFT
HQ-SOFT
Try

PCs_iterator = CurrentPCs->begin();while(1){	if (PCs_iterator == CurrentPCs->end())		break;        (*(PCs_iterator)).Update();	PCs_iterator++;}


(Or, something I find a bit easier to read)

for (PCs_iterator = CurrentPCs->begin(); PCs_iterator != CurrentPCs->end(); ++PCs_iterator){        PCs_iterator->Update();}


-HQ.
Zahlman
Zahlman
Or

std::for_each(CurrentPCs->begin(), CurrentPCs->end(), std::mem_fun_ref(&npc_object::Update));


As has been seen, writing loops manually is somewhat error-prone. ;)
Xai
Xai
just to reiterate the problem:

end() is a logical point one past the last item in the list - accessing and comparing it is legal, dereferencing it is not. The item one past end() is undefined garbage, invalid (undefined) to access in any way.

in an empty list list.begin() == list.end() ... so ++list.begin() is invalid for an empty list.
EmrldDrgn
EmrldDrgn
I've attempted to use your solutions, and while I think you've probably saved me from some problems down the line, it doesn't seem to have been the root of my current problem. Not only does your fix not work, but out of sheer frustration I re-wrote my code so that it never once used std::list.end(), and I'm still getting the same error. The reason I didn't want to post the code that causes the error earlier was that I wasn't sure if it WAS the code that caused the error. The actual exception is thrown somewhere in the middle of list.h, and although I did try to use a breakpoint to verify that that was where the error occured, I'm not sure that's what caused it, since fixing this didn't change anything and the breakpoint just had me stepping through millions of lines of assembly (an exaggeration) which I didn't understand. The actual error I'm getting is this:

Unhandled exception at 0x004190f4 in Tiling_Tryouts.exe: 0xC0000005: Access violation reading location 0xcdcdcddd.

And it occurs in:

	iterator end()		{	// return iterator for end of mutable sequence		return (iterator(_Myhead, this));		}


which is in list.h.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
Mastaba
Mastaba
What does your callstack look like when it crashes? What portion of your code was calling into list code?
iMalc
iMalc
Quote:
Original post by EmrldDrgn
Not only does your fix not work, but out of sheer frustration I re-wrote my code so that it never once used std::list.end(), and I'm still getting the same error.
The facts are that your original code was wrong and would do bad things in any program. Whereas the code others have posted to help you is correct and does not in itself have any bugs at all. To those familiar with STL, problems like this are obvious and easy to correct. Failing to show appreciation (or worse) for the useful help given, will not help your popularity or speediness of fixing the whole problem. You'd be hard-pressed to find many people giving better advice than Zahlman, so you should consider yourself lucky he is willing to help, and take his advice (and many others here) at every opportunity. I'm sure what you meant to say was: "Thankyou for your help so far, but I am having furthur problems..."[smile]

You've asked for help, and you certainly seem to need it! How about posting a decent amount of (your) code so that we can really get to the bottom of things for you? Where it crashes doesn't matter as it may be other bits of code that are corrupting the data structure. Any bit of (your) code that interacts with the std::list is worth having us take a look at. You'll probably learn much more than you expect!

Anyway, 0xCDCDCDCD is a debug value used to show up uninitialised variables. So there's a good chance this will come down to an uninitialised variable problem.
EmrldDrgn
EmrldDrgn
Quote:
Original post by iMalc
I'm sure what you meant to say was: "Thankyou for your help so far, but I am having furthur problems..."[smile]


That's exactly what I meant to say... the wording of my post was... unfortunate. I'm grateful to everyone who's helping me, and as I said above, you've probably saved me major problems down the line.

I'll post all the code I can find that interacts with std::list in the morning, when I can get at my development computer, but I wanted to correct what I was saying now, when I first noticed it. I'm sorry if I seem ungrateful. I'll look for an uninitialized variable in my code somewhere, as well.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~I program in C++, on MSVC++ '05 Express, and on Windows. Most of my programs are also for windows.
iMalc
iMalc
Hey that's okay man. I'm sure we can all see your good intentions.
We'll get to the bottom of this soon for ya.

Just a thought, have you tried turning your warning level up to W4 instead of the default W3? It sometimes finds bugs for ya! Don't necessarily feel obliged to change your code to prevent all warnings at that level, but do check them out in case some of them do happen to point to something that might not be quite right.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.