Re: [CODE] Restring...

From: Daniel Wickes (circle@wormsoft.demon.co.uk)
Date: 04/05/99


Hi,

I think your problem is probably that you're over-writing regions of memory.
The strcpy() function does not allocate the space for the string, as strdup()
would, before copying the contents over.  You'll be copying the contents of
that string to where ever your (probably uninitialised) pointers pointed.

Even if you allocated and freed the memory yourself the obj_file_elem
structure is written out in one fwrite() chunk, and you can't have pointers in
there, as you're going to write out the pointer, not the string it points to
(unless I'm very much mistaken -- sure to get a scolding response to this if I
am, though <g>).  This means when you read it back, the pointers are going to
point to who knows what.  You could make object.name a fixed length array e.g;

        struct obj_file_elem {
                obj_num item_number;
                char name[80];
                char short_desc[80];
                char long_desc[80];
                ...
        }

This would allow your code to work as-is, except for strings longer than 80
characters (use strncpy() to get around that) but it wouldn't be something I'd
recommend.  I'd go for a bigger change...

I think you have a couple of options; firstly you could save the objects
strings after the obj_file_elem in the file, using a tilde delimiter, as with
area files.  Then when reading back, you fread() the the objects data, but
fread_string() the three strings back.  I did this a while back before I
stopped being idle and ended up re-writing the save stuff, but I also made
some checks before saving the objects strings, checking that they weren't
identical to the ones of the original object.  The problem with saving the
strings for /every/ object is that you'll end up duplicating a lot of data.

The other solution is to not use fwrite()/fread() method to write out your
objects to a file.  In this case you might as well get rid of the
obj_file_elem structure as it ceases to be of any real use, all the
information you need is already in the object_data structure.  Whilst there
are a variety of options, I'd suggest you save the objects to a text file.
I've not checked out XAP objects, which are meant to do this, but I did
something very similar with our MUD.  You'll be able to add strings into the
new file with much greater ease.

I hope all that makes sense!  If not, I shall summarise by saying: check out
XAP objects <g>

-- Daniel

> I have now tried to copy the code for storing a character when
> storing an object for the purposes of restringing objects, but
> problems have occured. Whenever someone saves, the MUD crashes.
> The .core tells me nothing...
>     I will distribute my code so that any problems can be found.
>
> ---CODE---
> struct obj_file_elem {
>    obj_num item_number;
>    char *name;
>    char *short_desc;
>    char *long_desc;
>    ...
>    ..
>    .
> };
>
> int Obj_to_store_from(struct obj_data * obj, FILE * fl, int locate)
> {
>   int j;
>   struct obj_file_elem object;
>
>   object.item_number = GET_OBJ_VNUM(obj);
>   if (obj->name)
>     strcpy(object.name, obj->name);
>   else
>     *object.name = '\0';
>
>   if (obj->short_description)
>     strcpy(object.short_desc, obj->short_description);
>   else
>     *object.short_desc = '\0';
>
>   if (obj->description)
>     strcpy(object.long_desc, obj->description);
>   else
>     *object.long_desc = '\0';
>
>   ...
>   ..
>   .
> }
>
> struct obj_data *Obj_from_store_to(struct obj_file_elem object, int
> *locate)
> {
>   struct obj_data *obj;
>   int j;
>
>   if (real_object(object.item_number) > -1) {
>     obj = read_object(object.item_number, VIRTUAL);
>     *locate = (int) object.locate;
>     GET_OBJ_VAL(obj, 0) = object.value[0];
>     GET_OBJ_VAL(obj, 1) = object.value[1];
>     GET_OBJ_VAL(obj, 2) = object.value[2];
>     GET_OBJ_VAL(obj, 3) = object.value[3];
>     GET_OBJ_EXTRA(obj) = object.extra_flags;
>     GET_OBJ_WEIGHT(obj) = object.weight;
>     GET_OBJ_TIMER(obj) = object.timer;
>     GET_OBJ_LEVEL(obj) = object.level;
>     OBJ_SIZE(obj) = object.size;
>     obj->name = str_dup(object.name);
>     obj->short_description = str_dup(object.short_desc);
>     obj->description = str_dup(object.long_desc);
>     ...
>     ..
>     .
> }
>
> ---END OF CODE---


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST