Fixed size array vs alloca (or VLAs)
<p>When is <code>alloca()</code> preferable to memory allocated on the stack by declaring a fixed size array?</p>

<hr>

<p>Details:</p>

<p>As we know, <code>alloca()</code> is a controversial function. Used recklessly, it can cause stack overflow. Used judiciously, it can shave a few nanoseconds from a tight loop by avoiding heap allocation. In <a href="https://stackoverflow.com/q/1018853/1128289">this question</a> about why <code>alloca</code> is considered bad, several of the top answers advocate for the <em>occasional</em> use of <code>alloca</code>.</p>

<p>Another way to allocate from the stack is to simply declare a fixed size array. An example of this strategy can be found in the <code>arena</code> class in <a href="https://howardhinnant.github.io/short_alloc.h" rel="nofollow noreferrer">Howard Hinnant's stack allocator</a>. (That code is of course C++ but the concept is still applicable to C.)</p>

<p>What are the tradeoffs of using <code>alloca</code> vs a fixed size array? When, if ever, is one clearly preferable to the other? Is it simply a question of performance that should be empirically tested in each individual situation (when performance is a key goal and a hotspot has already been identified)? The fixed size array is more pessimistic -- it always allocates as much as we're willing to allocate on the stack -- but it's not clear whether this is good or bad.</p>

<p>Just to be as clear as possible, here's a very simple example of two function implementations where it seems reason to use either <code>alloca</code> or a fixed size array:</p>

<pre><code>#include &lt;alloca.h&gt;
#include &lt;assert.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

void foo_alloca(const size_t mem_needed) {
    printf("foo_alloca(%zu)\n", mem_needed);
    char* mem;
    bool used_malloc = false;
    if (mem_needed &lt;= 100)
        mem = alloca(mem_needed);
    else {
        mem = malloc(mem_needed);
        used_malloc = true;
    }
    assert(mem_needed != 0);
    // imagine we do something interesting with mem here
    mem[0] = 'a';
    mem[1] = 'b';
    mem[2] = 'c';
    mem[3] = '\0';
    puts(mem);
    if (used_malloc)
        free(mem);
}

void foo_fixed(const size_t mem_needed) {
    printf("foo_fixed(%zu)\n", mem_needed);
    char* mem;
    char stack_mem[100];
    bool used_malloc = false;
    if (mem_needed &lt;= 100)
        mem = stack_mem;
    else {
        mem = malloc(mem_needed);
        used_malloc = true;
    }
    assert(mem_needed != 0);
    // imagine we do something interesting with mem here
    mem[0] = 'a';
    mem[1] = 'b';
    mem[2] = 'c';
    mem[3] = '\0';
    puts(mem);
    if (used_malloc)
        free(mem);
}

int main()
{
    foo_alloca(30);
    foo_fixed(30);
    foo_alloca(120);
    foo_fixed(120);
}
</code></pre>

<p>Another option very similar to <code>alloca</code> is VLAs. As far as I know, memory obtained from <code>alloca</code> and VLAs have essentially the same behavior so the question applies to VLAs as well. If that understanding is wrong just mention it.</p>