C++ Garbage Collecter

Per Bothner per@bothner.com
Tue Aug 24 22:03:00 GMT 1999


Jeffrey A Law <law@cygnus.com> writes:

>   > There are a couple of coding techniques that can cause trouble.
>   > 1. Only storing (only) a pointer to an object that is outside the object,
>   > 
>   > for example
>   >     char * alloc() {
>   >         char * x = (char *) malloc( 100 );
>   >         return x-10;
>   >     }
>   > then the calling code knows to add 10 before using it.  This is highly
>   > perverse code and not likely to be found in practice, but it would break
>   > the Boehm GC.
> Actually, compilers do this internally sometimes as it allows them to
> generate more efficient loop code.

I don't think these statements are very relevant.  Yes, the compiler
sometimes does such re-writing, but that is not a problem for a conservative
collectors as long as there is still a pointer somewhere that points to
the actual base of the object.  And either you have a newly allocated
object that will be passed to someone, or it was an existing object
that was passed from somewhere (as an argument).  In either case, you
would have a pointer to the base object somewhere.

There is one problem I can think of:  Allocating a temporary object
is only used *local* to a function:

        char *x = (char*) gcmalloc(100);
        ... do stuff with x ...
        /* at this point x is dead */

Here you are the risk that x might be prematurely collected.  The
work-around is easy:  Don't do that.  Instead, use non gc-managed
memory for objects only used internally in a single function:

        class malloced {
            void *p;
            malloced(void *ptr) { p = ptr; }
            ~malloced() { free(p); }
        }

        char *x = (char*) malloc(100);
        malloced(x);
        ... do stuff with x ...
        /* malloced's finalizer will free x. */

There is at least one example of this "bad" use of gc'd memory in libgjc,
in the calls to _Jv_AllocBytes in java/lang/natSystem.cc.  I argued
against using gc'd memory for such buffers, mainly as a matter of style.
But I think we here have another reason to avoid it.  (In the case
at hand in natSystem.cc, I think we are safe, because the buffer is
passed as an argument to getpwuid_r, and there is no arithmetic on
the pointer.)

In practice, you are much more likely to get hosed by other problems
(including compiler bugs) than having the optimizer screw up
conservative collection.  It is a theoretical problem, but my
impression is that it is not an issue in practice.
-- 
	--Per Bothner
bothner@pacbell.net  per@bothner.com   http://home.pacbell.net/bothner/


More information about the Gcc mailing list