Stack-allocated arrays

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Nov 12 10:32:08 PST 2008


KennyTM~ wrote:
> The best solution I can think of, without compiler modification is a 
> struct/class that contains a static array member T[1024] and a dynamic 
> array member T[] initialized to null; and the code chooses which member 
> to use in the constructor. But this always occupies 1024*T.sizeof bytes 
> and there will always be a conditional (if) sticked to all access methods.

This entire discussion gets me thinking - could an alternate stack be a 
good (or even better) solution? Consider a global per-thread 
"superstack" - a growable region that allocates memory in large chunks 
and makes sub-chunks accessible in a strictly LIFO manner. The 
primitives of the superstack are as follows:

void* SuperStack.allocate(size_t bytes);
void SuperStack.free(size_t bytes);
size_t SuperStack.slack();

The SuperStack's management is a singly-linked list of large blocks. The 
slack function returns how many bytes are left over in the current 
chunk. If you request more than slack bytes, a new chunk is allocated 
etc. A SuperStack can grow indefinitely (and is susceptible to leaks).

Some convenience functions complete the picture:

T[] SuperStack.array(T)(size_t objects);
enum Uninitialized { yeahIKnow }
T[] SuperStack.array(T)(size_t objects, Uninitialized);

Freeing chunks should not be done immediately in order to avoid 
pathological behavior when a function repeatedly allocates and frees a 
chunk just to fulfill some small data needs.

With the SuperStack in place, code could look like this:

void foo(in size_t s)
{
     auto a = SuperStack.array(int)(s, Uninitialized.yeahIKnow);
     scope(exit) SuperStack.free(s);
     ... play with a ...
}

Is there interest for such a thing?


Andrei



More information about the Digitalmars-d mailing list