In your code only the pointer is allocated on the stack? the call to getmem() always allocates heap, not stack.
My code allocates ALL memory for the object on the stack, and that is free'd when that class goes out of scope. Of course that has certain risks if the stack size is not big enough, so the stack size must be carefully managed when you use my code. Your example has less risks in that regard, but you still need to call free on classes and Freemem on the local pointer.
Of course my example was not for a stack allocated class, but for a class that can be allocated in any memory, stack, heap, global variables (DATA segment), shared memory, file mapped memory, whatever.
Because as I said, the stack might not be the only target, but you may want to have a class in some other memory (like shared memory between processes, or global variable memory).
The heaptrc unit will reveal the difference between your code and my code: the allocations. In my example there are no heap allocations at all! except for the blocks necessary for the system unit.
It should be noted that I allocate a TStringList, which does internal allocations. Of course it's a bad example when you want to avoid heap allocations at all, but I think it's nice to visualize how to use custom allocation for already existing RTL classes.
Also your example calls alloca within the NewInstance, which as a function has it's own stack frame. So when the constructor calls this function, the memory will be allocated on the stack of that function, but when NewInstance returns, the stack frame is poped and you memory is gone.
I believe this is also the reason why you have problems with SEH exceptions, because you are referencing a stack frame which does not exist anymore. What you need to do is to allocate the stack memory first, and then hand it over to the class, to be used by the NewInstance function.
This is the main problem with a stack allocator, because It would be extremely nice to put it all encapsulated into it's own class with it's own functions, but alloca must be used within the function where the object shall be located, and therefore can't be encapsulated into another function
This is the reason why I have this weird CreateAt function, which just sets a global variable with the memory address, which will later be used by NewInstance:
class function TAnywhereStringList.CreateAt(mem: Pointer): TAnywhereStringList;
begin
DataPtr := mem;
Result := TAnywhereStringList.Create;
end;
Not the prettiest solution, but its necessary.