logoalt Hacker News

HarHarVeryFunnyyesterday at 6:21 PM8 repliesview on HN

This article is about Go, but I wonder how many C/C++ developers realize that you've always had the ability to allocate on the stack using alloca() rather than malloc().

Of course use cases are limited (variable length buffers/strings, etc) since the lifetime of anything on the stack has to match the lifetime of the stack frame (i.e the calling function), but it's super fast since it's just bumping up the stack pointer.


Replies

spacechild1yesterday at 6:36 PM

alloca() is super useful, but it's also quite dangerous because you can easily overflow the stack.

The obvious issue is that you can't know how much space is left on the stack, so you basically have to guess and pick an arbitrary "safe" size limit. This gets even more tricky when functions may be called recursively.

The more subtle issue is that the stack memory returned by alloca() has function scope and therefore you must never call it directly in a loop.

I use alloca() on a regular basis, but I have to say there are safer and better alternatives, depending on the particular use case: arena/frame allocators, threadlocal pseudo-stacks, static vectors, small vector optimizations, etc.

show 3 replies
anematodeyesterday at 6:44 PM

If you're not doing recursion, I prefer using an appropriately sized thread_local buffer in this scenario. Saves you the allocation and does the bookkeeping of having one per thread

rwmjyesterday at 6:31 PM

Most C compilers let you use variable length arrays on the stack. However they're problematic and mature code bases usually disable this (-Werror -Wvla) because if the size is derived from user input then it's exploitable.

dzdtyesterday at 8:23 PM

For purely historical reasons the C/C++ stack is "small" with exactly how small being outside of programmer control. So you have to avoid using the stack even if it would be the better solution. Otherwise you risk your program crashing/failing with stack overflow errors.

show 1 reply
up2isomorphismyesterday at 11:34 PM

It is a good thing many people do not know it. Since if you need this to squeeze that little performance window, you’d better know what you are doing.

ozgrakkurtyesterday at 6:25 PM

This is more of a patch/hack solution as far as I can understand.

You can just as well pass a heap allocated buffer + size around and allocate by incrementing/decrementing size.

Or even better use something like zig's FixedSizeAllocator.

Correct me if I am wrong please

show 1 reply
stackghostyesterday at 6:35 PM

alloca()'s availability and correctness/bugginess is platform dependent, so it probably sees only niche usage since it's not portable. Furthermore, even its man page discourages its use in the general case:

>The alloca() function is machine- and compiler-dependent. Because it allocates from the stack, it's faster than malloc(3) and free(3). In certain cases, it can also simplify memory deallocation in applications that use longjmp(3) or siglongjmp(3). Otherwise, its use is discouraged.

Furthermore:

>The alloca() function returns a pointer to the beginning of the allocated space. If the allocation causes stack overflow, program behavior is undefined.

https://man7.org/linux/man-pages/man3/alloca.3.html

lstoddyesterday at 7:41 PM

It becames super slow when you bump that pointer into a page that's missing from the TLB.

show 1 reply