DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH
 

(guile.info.gz) A Common Mistake In Allocating Smobs

Info Catalog (guile.info.gz) Garbage Collecting Smobs (guile.info.gz) Defining New Types (Smobs) (guile.info.gz) Garbage Collecting Simple Smobs
 
 18.3.5 A Common Mistake In Allocating Smobs
 -------------------------------------------
 
 When constructing new objects, you must be careful that the garbage
 collector can always find any new objects you allocate.  For example,
 suppose we wrote the `make_image' function this way:
 
      SCM
      make_image (SCM name, SCM s_width, SCM s_height)
      {
        struct image *image;
        SCM image_smob;
        int width, height;
 
        SCM_ASSERT (SCM_STRINGP (name), name, SCM_ARG1, "make-image");
        SCM_ASSERT (SCM_INUMP (s_width),  s_width,  SCM_ARG2, "make-image");
        SCM_ASSERT (SCM_INUMP (s_height), s_height, SCM_ARG3, "make-image");
 
        width = SCM_INUM (s_width);
        height = SCM_INUM (s_height);
 
        image = (struct image *) scm_must_malloc (sizeof (struct image), "image");
        image->width = width;
        image->height = height;
        image->pixels = scm_must_malloc (width * height, "image pixels");
 
        /* THESE TWO LINES HAVE CHANGED: */
        image->name = scm_string_copy (name);
        image->update_func = scm_c_define_gsubr (...);
 
        SCM_NEWCELL (image_smob);
        SCM_SET_CELL_WORD_1 (image_smob, image);
        SCM_SET_CELL_TYPE (image_smob, image_tag);
 
        return image_smob;
      }
 
    This code is incorrect.  The calls to `scm_string_copy' and
 `scm_c_define_gsubr' allocate fresh objects.  Allocating any new object
 may cause the garbage collector to run.  If `scm_c_define_gsubr'
 invokes a collection, the garbage collector has no way to discover that
 `image->name' points to the new string object; the `image' structure is
 not yet part of any Scheme object, so the garbage collector will not
 traverse it.  Since the garbage collector cannot find any references to
 the new string object, it will free it, leaving `image' pointing to a
 dead object.
 
    A correct implementation might say, instead:
 
        image->name = SCM_BOOL_F;
        image->update_func = SCM_BOOL_F;
 
        SCM_NEWCELL (image_smob);
        SCM_SET_CELL_WORD_1 (image_smob, image);
        SCM_SET_CELL_TYPE (image_smob, image_tag);
 
        image->name = scm_string_copy (name);
        image->update_func = scm_c_define_gsubr (...);
 
        return image_smob;
 
    Now, by the time we allocate the new string and function objects,
 `image_smob' points to `image'.  If the garbage collector scans the
 stack, it will find a reference to `image_smob' and traverse `image',
 so any objects `image' points to will be preserved.
 
Info Catalog (guile.info.gz) Garbage Collecting Smobs (guile.info.gz) Defining New Types (Smobs) (guile.info.gz) Garbage Collecting Simple Smobs
automatically generated byinfo2html