Pointers pissing me off

Locked
User avatar
Eraser
Posts: 19174
Joined: Fri Dec 01, 2000 8:00 am

Pointers pissing me off

Post by Eraser »

I'm not much of a C programmer because my grasp of pointers is still flimsy at best.
So I have the following situation right now. In cgame, I have the following function:

Code: Select all

qboolean CG_DrawSinglePlayerObjectives( void ) {
	int i;
	vec4_t color;
	playerscore_t *scores;
	
	
	//q3w: there's a bunch of unrelated stuff here
	
	
	//draw level score
	COM_CalculatePlayerScore( scores, cg.snap->ps.persistant, CG_GetAccuracy(), CG_GetSkill() );

    //q3w: the bits below aren't really important right now
	i = strlen(va("%i", scores->totalScore));
	CG_DrawBigStringColor( 496 - (i * BIGCHAR_WIDTH), 343, va("%i", scores->totalScore), color);	

	if ( ++cg.deferredPlayerLoading > 10 ) {
		CG_LoadDeferredPlayers();
	}

	return qtrue;
}
The playerscore_t struct is defined in q_shared.h like this:

Code: Select all

typedef struct playerscore_s {
	int carnageScore;
	int accuracy;
	int accuracyScore;
	int deaths;
	int deathsScore;
	int secretsFound;
	int secretsCount;
	int secretsScore;
	int subtotalScore;
	float skill;
	float skillModifier;
	int skillScore;
	int totalScore;
} playerscore_t;
In q_shared.c, the COM_CalculatePlayerScore function is defined. Right now, all it does is set the carnageScore variable in the struct to 0:

Code: Select all

void COM_CalculatePlayerScore(playerscore_t *scores, int persistant[MAX_PERSISTANT], int accuracy, float skill) {
	scores->totalScore = 0;
}
So far so good, this appears to work well.
I also have another function which calls the COM_CalculatePlayerScore function:

Code: Select all

void CG_DrawSinglePlayerIntermission( void ) {
	vec4_t color;
	playerscore_t *scores;
	
	color[0] = 1;
	color[1] = 1;
	color[2] = 1;
	color[3] = 1;
	
	COM_CalculatePlayerScore( scores, cg.snap->ps.persistant, CG_GetAccuracy(), CG_GetSkill() );
}
When the intermission screen is supposed to be shown, however, the game crashes.
I modified the COM_CalculatePlayerScore function slightly to see what was happening:

Code: Select all

void COM_CalculatePlayerScore(playerscore_t *scores, int persistant[MAX_PERSISTANT], int accuracy, float skill) {
	if (score) {
		Com_Printf("Yes\n");
		scores->totalScore = 0;
	} else {
		Com_Printf("No\n");
	}
}
Now when displaying the objectives (the function that went right), it simply outputs a lot of "yes"-es in the console and it works well. However, when the intermission screen needs to be shown, it outputs a lot of "no"'s.
You may wonder why that color[0] = 1 etc is in there. Well, at one point I commented those out to have as little unrelated code in there as possible and that caused the game to go crashing again. I assume that "scores" inside the COM_CalculatePlayerScore was no longer NULL but also not a playerscore_t struct, but something else entirely (not sure what). I was pretty much dumbstruck to find that these seemingly unrelated lines of code could have such an impact.

So you see, I have no clue what I'm doing and it's starting to annoy me. Can any of you gurus point me in the right way?
Oh and one more thing, I tried to have my COM_CalculatePlayerScores return a playerscore_t struct as well as have it return a pointer to such a struct but I couldn't get either of those cases to work at all, so I figured passing a pointer argument to the method was the next best thing and that worked, until now.

This is what you get for coding in Java and C# too much :(

edit:
oh, I just commented out the stuff I had marked as "there's a bunch of unrelated stuff here" in the first function listed and now the game crashes when displaying the objectives as well :(
^misantropia^
Posts: 4022
Joined: Sat Mar 12, 2005 6:24 pm

Re: Pointers pissing me off

Post by ^misantropia^ »

Eraser wrote:

Code: Select all

void CG_DrawSinglePlayerIntermission( void ) {
	vec4_t color;
	playerscore_t *scores;
	
	color[0] = 1;
	color[1] = 1;
	color[2] = 1;
	color[3] = 1;
	
	COM_CalculatePlayerScore( scores, cg.snap->ps.persistant, CG_GetAccuracy(), CG_GetSkill() );
}
You're passing an uninitialized scores pointer to COM_CalculatePlayerScore().
User avatar
Eraser
Posts: 19174
Joined: Fri Dec 01, 2000 8:00 am

Re: Pointers pissing me off

Post by Eraser »

Should I use memset for that? I remember that crashing the whole thing as well, but I'll try again. But why does it work correctly in the other function then? I don't initialize it there either.
User avatar
Eraser
Posts: 19174
Joined: Fri Dec 01, 2000 8:00 am

Re: Pointers pissing me off

Post by Eraser »

Whoa, I got it fixed.
I forgot to declare the COM_CalculatePlayerScore function in q_shared.h so I guess that messed it up. But when I realized this, I was halfway through rewriting the code so that COM_CalculatePlayerScore simply returns the struct (not a pointer to it) so that I don't have to pass a pointer to a struct to the method. I couldn't get the return-a-struct method working before but I guess that was due to the function not being declared in q_shared.h.
Locked