Should GC.realloc(null, N) be the equivalent of GC.calloc or GC.malloc?

Ali Çehreli via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 17 14:52:50 PDT 2014


When called with an existing buffer, GC.realloc conditionally clears the 
newly extended part of the memory. An excerpt from druntime/src/gc/gc.d:

void *realloc(void *p, size_t size, uint bits = 0, size_t *alloc_size = 
null, const TypeInfo ti = null) nothrow
{
     // ...

     if (p !is oldp && !(bits & BlkAttr.NO_SCAN))
     {
         memset(p + size, 0, *alloc_size - size);
     }

     return p;
}

(Disclaimer: Although undocumented, I assume that clearing the memory is 
an intended feature of GC.realloc.)

With that behavior in mind, when called with null, should GC.realloc do 
the same thing to the entirety of the newly allocated memory?

I think it should. Otherwise, the idiom of lazily extending a memory 
buffer with realloc cannot be applied because one needs to memset after 
the first call explicitly:

import core.memory;

void main()
{
     ubyte* p = null;

     // Note that p is null for the first call
     p = cast(ubyte*)GC.realloc(p, 10);
     p = cast(ubyte*)GC.realloc(p, 20);

     // There are non-zero bytes in the first half:
     foreach (i; 0 .. 10) {
         assert(p[i] == 0); // <-- Assertion fails for some i!
     }
}

Ali


More information about the Digitalmars-d mailing list