This is a hard task for me for some reason cuz i can never get this to work. I need to have a structure i've made go off of the character data, similar to the pcdata...
Typedef struct mystruct MYSTRUCT;
struct mystruct
{
int test;
};
and in struct char_data i have MYSTRUCT *mystruct;
I have in another function this...
ch->mystruct->test = 10;
ch_printf( ch, "%d/n/r", ch->mystruct->test );
everytime i use the function, the mud crashes...its smaug...and the line of problem is ch->mystruct->test = 10;
Alright I tried to work with this by making my powerlevel system into that form... First off these are the errors.
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
75 return URANGE( PWR_MIN, (ch->energy->capacity), PWR_MAX );
(gdb) bt
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
#1 0x080f2c32 in get_plvl_curr (ch=0x83a4508) at plvl.c:87
#2 0x08123f33 in char_update () at update.c:943
#3 0x08125c91 in update_handler () at update.c:2058
#4 0x08096d66 in game_loop () at comm.c:722
#5 0x08096655 in main (argc=2, argv=0xbffff874) at comm.c:329
#6 0x40063d06 in __libc_start_main () from /lib/libc.so.6
(gdb)
the ch->energy is made from the CREATE command. All i get is a segmentation fault.
Everything is exactly the way as if i did it with mystruct. The only thing different is the categories. Help?
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
75 return URANGE( PWR_MIN, (ch->energy->capacity), PWR_MAX );
(gdb) bt
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
#1 0x080f2c32 in get_plvl_curr (ch=0x83a4508) at plvl.c:87
Somehow, you managed to use a null character. The problem isn't in ch->energy, it's in ch itself.
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
#1 0x080f2c32 in get_plvl_curr (ch=0x83a4508) at plvl.c:87
Looks to me like you should inspect get_plvl_curr and see why it didnt pass ch along, or why it made ch NULL. Paste the function here and we could probably help.
//THE CURRENT STORED POWER OF A CHARACTER//
long get_plvl_curr( CHAR_DATA *ch )
{
return URANGE( 0, ((get_plvl_maxx(ch)) - (ch->energy->depleted)), (get_plvl_maxx(ch)) );
}
//THE TOTAL POWERLEVEL OF A CHARACTER//
long get_plvl_maxx( CHAR_DATA *ch )
{
return URANGE( PWR_MIN, (ch->energy->capacity), PWR_MAX );
}
those are the two functions that are shown in that statement...
Ok to try and make things more clearer, I'm going to paste my code and put where things are called.
In Mud.h
after structure types, with the rest of them, i put...
typedef struct energy_data ENERGY;
in char_data and in mob_index_data i put...
ENERGY * energy;
somewhat space below I have the structure itself...
struct energy_data
{
long capacity;
long generate;
long prepared;
long depleted;
};
in plvl.c i have these functions....
//THE TOTAL POWERLEVEL OF A CHARACTER//
long get_plvl_maxx( CHAR_DATA *ch )
{
return URANGE( PWR_MIN, (ch->energy->capacity), PWR_MAX );
}
//THE AVAILABLE POWER OF A CHARACTER//
long get_plvl_av( CHAR_DATA *ch )
{
return URANGE( 0, ch->energy->prepared, get_plvl_maxx(ch) );
}
//THE CURRENT STORED POWER OF A CHARACTER//
long get_plvl_curr( CHAR_DATA *ch )
{
return URANGE( 0, ((get_plvl_maxx(ch)) - (ch->energy->depleted)), (get_plvl_maxx(ch)) );
}
//THE CURRENT POWER UP//
long get_plvl_up( CHAR_DATA *ch )
{
return URANGE( 0, (ch->energy->generate), PWR_MAX );
}
in comm.c as a part of the prompt and fprompt i have..,
case 'P':
stat = get_plvl_maxx(ch); /*Max Power Level*/
break;
case 'p':
stat = get_plvl_curr(ch); /*Current Power Level*/
break;
case 'E':
stat = get_plvl_up(ch); /* Power Up */
break;
case 'e':
stat = get_plvl_av(ch); /* Energy */
break;
in update.c i as a part of the regenerate section, i put..
if ( get_plvl_curr(ch) < get_plvl_maxx(ch) )
ch->energy->depleted -= plvl_curr_gain(ch);
thats everything that the segfault involves...here is the segfault again
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
75 return URANGE( PWR_MIN, (ch->energy->capacity), PWR_MAX );
(gdb) bt
#0 0x080f2bde in get_plvl_maxx (ch=0x0) at plvl.c:75
#1 0x080f2c4f in get_plvl_curr (ch=0x83a4508) at plvl.c:87
#2 0x08123f2b in char_update () at update.c:944
#3 0x08125c89 in update_handler () at update.c:2061
#4 0x08096d66 in game_loop () at comm.c:722
#5 0x08096655 in main (argc=2, argv=0xbfffeb64) at comm.c:329
#6 0x40063d06 in __libc_start_main () from /lib/libc.so.6
It does this right on the startup of the mud. Log is fine. Before i switched the system to its own structure, it used to be ch->generate, ch->capacity, and so on so forth. It worked fine then. After I switched and followed the examples given to me, it gives me that segfault. My theory is that its in the energy->portion but i do not understand how considering that I've added the CREATE ( ch->energy, ENERGY, 1 ); into the save.c file with the rest of the stats...Please help me...
but that sparks another question because i'm definately going to need this with the next thing i code. Is this problem gonna keep showing up? If so, i'd have to find out how to fix it and fix it now.
One problem you might be having is that the ENERGY structure is [b]only[/b] created [b]if[/b] the load function finds an entry in the pfile.
This doesn't explain the null ch problem, but it's still something to fix.
You want to create the energy structure like you were told at the same place the PCDATA structure is created, not in the part where you read the data from the file. :)
Mystery bugs like this are best found and fixed by tools other than GDB. It's possible the null ch is coming from something unrelated and this code is just what finally brought the problem to light. Time to bust out Valgrind and have a go if possible. Generally Valgrind will give you a much more detailed breakdown of how something like this happens.
One possibility is that not creating the ch->energy struct if there isn't a pfile entry is that it COULD be causing stack corruption which has been known to lead to bad GDB traces. It might have caused ch to point to NULL data somehow. Stranger things have happened.
Valgrind takes a tons of processor and memory, and on most pay accounts you'll have both of those limited, so its not always possible. I eventually had to dual boot and run my mud on a linux install.