09 Jun, 2010, Oliver wrote in the 1st comment:
Votes: 0
All right. Here's the deal, guys. I recently wrote a piece of code for an Introduction system (so that players can introduce themselves to other players, at which point they see a name instead of a short description). It all worked fine and well…. up until the write/read functions. Allow me to show you:

//fwrite intros
INTRO_DATA *intros;

for ( intros = ch->intros; intros != NULL; intros = intros->next )
fprintf( fp, "Intro '%s' '%s' %ld\n",

if (!str_cmp(word, "Intro"))
log_string("Intro found.");

INTRO_DATA *intro;
intro = new_intro();

intro->real_name = fread_word(fp);
intro->known_name = fread_word(fp);
intro->id = fread_number(fp);

intro->next = ch->intros;
ch->intros = intro;

fMatch = TRUE;

Those seem pretty simple, right? Well. During pfile loading, everything works fine and they seem to load the data fields with the correct strings.

So let's say I manually insert an entry in a pfile. It will be:
Intro 'Oliver' 'Oliver' 500

I put some log_strings in the middle of the freading of intros just to see what they're loading as there. It tells me that 'Oliver' is being loaded into real_name, 'Oliver' is being loaded into known_name, and 500 is being loaded into the ID. But the thing is.. as soon as I type 'test' on that character (test iterates through all Intros and displays their data)? I see this:

You know END as END, id number 500.

If I save/quit, it writes END END in the pfile. So I searched through all my code to see where this is possibly leaking through from. The offending line?

fwrite_char( ch, fp );
if ( ch->carrying != NULL )
fwrite_obj( ch, ch->carrying, fp, 0 );
/* save the pets */
if (ch->pet != NULL && ch->pet->in_room == ch->in_room)
[b][i] fprintf( fp, "#END\n" );[/i][/b]

in save_char_obj(). If I change "#END" to "#TEST", there, Intro data shows up as:

You know TEST as TEST, id 500.

I have no clue what's going on here, guys, and I can't fix it. I'd appreciate any help.
09 Jun, 2010, Tonitrus wrote in the 2nd comment:
Votes: 0
Sounds like an allocation issue. You should probably include the code for new_intro as well.

[Edit: Actually, that probably doesn't matter. Maybe I should read before responding. Unless there's something very screwy about your codebase, you'll need to use something like:
[code]intro->real_name = wtfever_alloc(fread_word(fp));[/code]
(I don't know what your codebase uses to allocate strings. You're assigning a string without allocating it, which means its value will most likely change.)]
09 Jun, 2010, Oliver wrote in the 3rd comment:
Votes: 0
I don't think that's the case, and this is why:

INTRO_DATA *new_intro(void)
INTRO_DATA *intro;

intro = alloc_perm(sizeof(INTRO_DATA) );

intro->real_name = str_dup("");
intro->known_name = str_dup("");
intro->id = 0;
intro->next = NULL;

return intro;

If I am not much mistaken, it's not a problem with allocation.

… Edit: I changed it to str_dup(fread_word(fp)), and it seems to be working now. As a matter of curiosity, is this because fread_word() does not malloc while fread_string() does? That could be the problem. I'm actually pretty bad at dealing with file-reading.
09 Jun, 2010, Tonitrus wrote in the 4th comment:
Votes: 0
What you're doing there is allocating an empty string to real_name. Then you're pointing real_name to the result of fread_word() which changes every single time you read a word, meaning real_name will inevitably point the the last word read in by fread_word(). What you should do instead is point real_name to NULL in new_intro() and then str_dup() the results of fread_word().
09 Jun, 2010, Oliver wrote in the 5th comment:
Votes: 0
Well. See above edit! That's what I did.

Thanks, man. 'ppreciate the help. It was a pretty dumb mistake, but I guess it's just one of those things, 'eh?