NULL exception help

Started by
12 comments, last by fooman_69 18 years, 11 months ago
Hiya! I've been getting this NULL pointer exception in the 2nd run-through of my game loop, the project is here. It's a strange one, so I'd be very happy if anyone can help me. Please don't yell at me about such things as my ofstream error logs because error logging is not my main focus at the moment, although it should be indeed. Anyways, I store my sprites for each character(Entity) in an array linkedlist. So I have a list for the breathing animations at the moment, but each set of animations will have their own index in the array once I can figure this issue out. So when I run through the gameloop, the 2nd run-through in the debugger tells me that my player Entity's currentImage is now non-existant. I can NOT figure out why.
Advertisement
I don't want to look at it, but some assert statements might be helpful.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Why not run the debugger until you determine where the image becomes nonexistant?
1)Always check your pointers before using them.
//example:
if(pPointer != NULL)
{
pPointer->UseMe();
}
else
{
OutputDebugString(TEXT("Encountered pPointer is NULL!\r\n");
}

2) Check every usage of the pointer that becomes NULL.

Can you point us the exact codefragment when the exception occurs?
(So we can see how safe it is programmed)

greetz,

Ward
Quote:
if(pPointer != NULL)
{
pPointer->UseMe();
}
else
{
OutputDebugString(TEXT("Encountered pPointer is NULL!\r\n");
}

That's expensive! By all means test them, or atleast at the begining of each function or something, but don't test for null on a pointer which you "know" can't be, assert instead (as the first answer said). This way there is no runtime overhead in release builds.

#include <assert.h>assert(pPointer);pPointer->UseMe();


And yeah, use the debugger. The debugger will be quicker in the short term. The asserts will save you time in the long run.
Checking every pointer before using them seems to be a bit of overkill, because you do get an exception, which breaks into the debugger. Then just use your debugger to check which variable that was NULL.

Some general comments on your program: Why do you compile it with .NET Managed Excetions, when you use only plain C++? Is this just an oversight? You can change the setting in Project Options -> General -> Use Managed Extensions.

Why do you implement your own linked list, when STL has a implementation in std::list. That would have avoided this bug....

You are welcome to ask again if you do not find the pointer with the wrong value.
Quote:Original post by Squirm
That's expensive! By all means test them, or atleast at the begining of each function or something, but don't test for null on a pointer which you "know" can't be, assert instead (as the first answer said). This way there is no runtime overhead in release builds.


I've had some experiences before that some variables where not properly initialized. In debugmode they are mostly initialized to zeroes, but in releasemode then where initialized to mostly a random value (all depending on the platform).
Because it is possible the originator of the problem of 'this thread' has made an initialisation error, this will still result in a crash free program.

Of course another tip will be checking all initialisations of all variables and set them properly.
Hello ppl, thanks for the criticism and tips. I used my own LinkedList because... just because it was an added challenge and I wanted to see if I could sort this problem out now that I have it.
I HAVE used the debugger a ton of times before posting this. I have tried and tried but I can NOT determine where the pointer becomes NULL. The first run through the game loop the characterList's values are fine. The images show as they should, but the 2nd run through the loop (I swear I do not change anything with the Entity or call GetNext() on the LinkedList), the characterList suddenly has NULL pointers to the current spot, next, and previous spot as well. So when I call
characterList[currentPlace].GetCurrent();
I get the NULL pointer.

I guess I should look into using STL's list.
Quote:Some general comments on your program: Why do you compile it with .NET Managed Excetions, when you use only plain C++? Is this just an oversight? You can change the setting in Project Options -> General -> Use Managed Extensions.
What exactly ARE managed extensions?
Have you considered the problem of a stack overwrite?
Perhaps do an array bounds checking (by doing code review).
An overwrite of 1 byte is enought to mess up the stack and give unwanted results.

Again, can you give us a downscaled example of your code that gives the exception?
I've done a quick code review (debugging) and
after changing the line:

void Video::Render(HDC &hDC, Entity ent1, Entity ent2)

to

void Video::Render(HDC &hDC, Entity *ent1, Entity *ent2)

You must also then replace ever ent1.function() by a
ent1->function(), for both ent1 and ent2 in the Render procedure.
And call the Render procedure from the main loop like this:
Render(hDC, player1, player2); (the * signs must be removed)

I can get the program run. I don't know what you expect from the output, but at least it does not crash.

What you were doing there was passing physical copies of and instance of Entity-class. The Render procedure on his turn calls methods that changed several membervariables of those copies. The changings are persistent on the dynamic memory variables, but not on the stack memory variables (because these are copies).
This, according to me, can result in strange behaviour (and possibly a crash).

Hope you understand this bugfix.

greetz,

Ward







This topic is closed to new replies.

Advertisement