Where should I declare an instance of a struct?

Posted by Golg on Sat 05 Mar 2005 10:54 PM — 15 posts, 41,448 views.

#0
I created a new struct in mud.h to hold globally available data that should be the same for all characters, so it must be outside of pc_data. Upon MUD startup, an instance of it should be declared and memory allocated for it.

The problem is, I'm not sure where I should declare it, and I don't seem to be able to find where other structs are created. If you could help me, I'd really appreciate it...this whole thing is giving me a headache.
USA #1
Do you intend for this data to be specific to each character, or do you intend it to be global across the whole MUD?
#2
Global across the entire MUD...I know how to put things in pc_data or char_data already.
USA #3
OK. You'll want to create a global variable of that type, which you can do in comm.c for example. Look at the declarations for other global variables, such as first_char, and make one like that. You don't need to make it a pointer, you can just declare one on the stack, I suppose. Then, in mud.h, you'll want the same thing with extern in front - that means that it's not a declaration per se but a sort of forward declaration, meaning: "this symbol exists, but is somewhere else".

Let me know if that made sense. :)
#4
Yes, that makes sense, thanks :P
#5
Oh yeah. I also want a variable in each instance of the struct to be initialized when the MUD is started, and I need to allocate memory for the pointer to the struct...do you know where I should do these two things?

Thanks.
USA #6
Quote:
each instance of the struct
I thought the whole point was to have just one instance of the struct, and have it be global...
Quote:
allocate memory for the pointer to the struct
Inside db.c, in one of the load functions, most likely. Or, I suppose, inside the main function. It depends on what you want to do with your struct and what information it needs to have lying around.
#7
I'll have a struct array that'll be accessed from a new function in act_info.c and act_comm.c. It'll be for a channel history command, and it will hold a double pointer (I'm not sure what the term is...char **history) to hold the messages and an int holding the index representing the last message gotten. It will only hold something around 10 messages, so the messages will be recycled.
Canada #8
You could fairly easily incorporate that into sys_data and have it created and initialized with the rest of sys_data.
#9
Oh, thanks for pointing out system_data. I didn't realize that it existed. Now, I need to initialize index to 0 and allocate memory for everything when the mud starts up...where's the best place for that?
USA #10
If you're putting it into sys_data, find out where the rest of sys_data is initialized and do it in the same place.
#11
Thanks...I don't think my mind was adhering to common sense at the time of my last post.

Now, a problem that's suddenly popping up.

This line works:
sysdata.channel_history[chanhist_num]->message[sysdata.channel_history[chanhist_num]->lm_index] = "test";
But this segfaults:
strcpy(sysdata.channel_history[chanhist_num]->message[sysdata.channel_history[chanhist_num]->lm_index], argument);

Any idea why? I tried strncpy, but it still explodes. argument is a char * that holds the message sent by a MUD command like "chat blah".
USA #12
Quote:
sysdata.channel_history[chanhist_num]->message[sysdata.channel_history[chanhist_num]->lm_index] = "test";
This line is assigning the pointer value of the constant string 'test' to that long pointer.
Quote:
strcpy(sysdata.channel_history[chanhist_num]->message[sysdata.channel_history[chanhist_num]->lm_index], argument)
This on the other hand is trying to copy into the memory located at that long pointer, and chances are you have not allocated any memory there.

One works at not the other because in the first case, you are assigning a pointer to constant memory (strings like that are held in the executable as plain-text constants), but in the second case, you're trying to copy into memory that does not exist.
#13
Ah, thank you for pointing that out...I was thinking along the wrong lines again. I allocated memory for each string in boot_db.c and then set each string to NULL. Oops.
USA #14
Well, this may seem like nitpicking but a precise vocabulary sometimes helps clear things up in your head (it does for me, in any case.) You're not actually setting the string to null, but the string pointer. A string is a sequence of bytes, terminated by a null byte. So setting a string to null means (literally) pretty much that you have set the first byte to null, although most people do not use the term this way. The string pointer is the bit that needs to point towards a block of memory somewhere.

Forgive me if this feels obvious and you already knew it, but I figured it might be useful if you didn't.