Fixed array size vs alloca (or VLAs)

When is the alloca()preferred memory allocated on the stack declaring a fixed-size array?


More details:

As we know, a alloca()controversial function. Used recklessly, this can cause a stack overflow. Used wisely, it can shave a few nanoseconds from a tight loop, avoiding heap distribution. In this question about why allocait is considered bad, some of the best answers protect accidental use alloca.

Another way to allocate from the stack is to simply declare an array of a fixed size. An example of this strategy can be found in the class arenaat Howard Hinnant Stack Distributor . (This code is, of course, C ++, but the concept is still applicable to C.)

What are the trade-offs of using allocacompared to a fixed-size array? When, if ever, is he clearly preferable to another? Is it just a performance issue that needs to be empirically tested in every single situation (when performance is a key goal and a hot spot has already been identified)? An array of fixed size is more pessimistic - it always allocates as much as we want to allocate on the stack, but it is not clear whether this is good or bad.

To be as clear as possible, here is a very simple example of two implementations of functions in which it seems appropriate to use either allocaan array of fixed size:

#include <alloca.h>
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

void foo_alloca(const size_t mem_needed) {
    printf("foo_alloca(%zu)\n", mem_needed);
    char* mem;
    bool used_malloc = false;
    if (mem_needed <= 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 <= 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);
}

Another option very similar to allocais VLA. As far as I know, memory obtained from allocaand VLA has essentially the same behavior, so the question applies to VLA as well. If this understanding is incorrect, just indicate it.

+4
source share
1 answer

What are the trade-offs of using alloca()compared to a fixed-size array?

  • . alloca() C. .

  • Analyzability. , , . alloc() / .

  • . alloca() . .

  • / , , , . .

  • / VLA alloca(), , C99, C11.

+3

Source: https://habr.com/ru/post/1656632/


All Articles