C, C++: Alocação dinâmica na pilha

Palavras-chave: non-constant initializers, dynamic stack allocation

Muitas vezes alocamos memória para um buffer baseado em um tamanho que é passado como parâmetro para a função. Como no seguinte exemplo:

void foobar (size_t size)
{
        char *buffer = malloc(size * 2);

No gcc existe uma extensão pouco conhecida, mas bastante útil, chamada non-constant initializers. Usando este recurso, a função poderia ser simplificada para:

void foobar (size_t size)
{
        char buffer[size * 2];

A variável é alocada na pilha com um tamanho dinâmico que depende do valor passado como parâmetro e a desalocação do buffer é feita no retorno da função.

This entry was posted in C, CPP. Bookmark the permalink.

6 Responses to C, C++: Alocação dinâmica na pilha

  1. Ulisses Furquim says:

    Non-constant initializers era uma extensão que o GCC implementava mesmo antes de entrar no padrão ISO C99 e também já fazia parte do padrão de C++. Aliás, não só essa como outras extensões do GCC passaram a fazer parte do padrão C99, como designated initializers. Porém, a sintaxe de designated initializers no padrão C99 é um pouco diferente da extensão do GCC, e se não me engano o GCC suporta ambas.

  2. Você também pode usar “alloca()”, que tem o mesmo comportamento (ie: não precisa liberar, mas também não pode sair do escopo).

  3. O maior problema de usar a “técnica” citada nesta dica é não poder checar o retorno da alocação. Se não tiver memória, é crash.

  4. Ademar Reis says:

    Eu tenho um pouco de trauma com a alloca() e não a recomendo. Além disso, veja o que a manpage diz:

    “””
    BUGS
    The alloca() function is machine and compiler dependent. On many systems its implementation is buggy. Its use is discouraged.

    On many systems alloca() cannot be used inside the list of arguments of a function call, because the stack space reserved by alloca() would appear on the stack in the middle of the space for the function arguments.
    “””

    /me torçe para que a formatação não saia muito quebrada (cadê o botão preview?) :-)

    Não sei se a alocação dinâmica do gcc tem os mesmos problemas da alloca(), mas se tiver, acho melhor não utilizar.

  5. Marcus says:

    Uma correção ao comentário do Ulisses:

    Esse recurso existe como extensão no GCC e no padrão C99.
    Em C++ padrão não existe. Mas tudo bem, em C++ podemos usar um std::vector (tá certo que não aloca na pilha, mas sim no heap; mas o que importa é que o vector é desalocado automaticamente no fim da função)

  6. Leonardo says:

    Considere expressões matemáticas onde aparecem três tipos de delimitadores de escopo: parênteses ( ), colchetes [ ] e chaves { }. Por exemplo:

    4 + { A – 2 × [ B / ( 5 + D)] + (2 – F)} – {K × [4 – J ]}

    Utilizando uma estrutura de pilha e chamadas a funções cujos protótipos estão definidos abaixo, construa uma função que valide (retorne true ou false) uma expressão de entrada qualquer avaliando, apenas, uma correspondência coerente de delimitadores.
    Me deem uma luz, preciso fazer isso, mas não sei por onde começar.

    // empilha val
    void Empilha(char val)
    // desempilha e retorna o elemento desempilhado. Retorna false se pilha vazia
    char Desempilha()

    Exemplos de expressões incorretas:

    (A + B]
    [(B – C] + 4)
    A + }F × (C + 1)}

Comments are closed.