cmemory-managementlocal-variablesstack-pointerstatic-allocation

Deallocating locally defined variables in C


Assume we have the following piece of code:

void foo() {
  char buffer[100];
}

Is there a (preferably portable) way in C to deallocate buffer from the runtime stack (akin to add esp, 100 in assembly), before foo() returns?


Solution

  • No. The best you can do in C is use scopes:

    void foo()
    {
        {
            char buffer[100];
        }
    }
    

    and rely on the compiler to consider the 100 bytes of buffer available again after the inner scope exits. Unfortunately, this is not guaranteed by the standard and you need to depend on the compiler. For example, consider the following program on a typical Linux machine with a stack space of 8192KB (ulimit -s):

    #include <stdio.h>
    
    int main(void)
    {
        {
            char buffer1[8192 * 800] = { 0 };
            ((char volatile *)buffer1)[0] = buffer1[0];
            printf("%p\n", buffer1);
        }
    
        {
            char buffer2[8192 * 800] = { 0 };
            ((char volatile *)buffer2)[0] = buffer2[0];
            printf("%p\n", buffer2);
        }
    
        return 0;
    }
    

    (The weird cast is to prevent the buffer variables from being optimized out.)

    The program will overflow the available stack space on some compilers when not building with optimizations. clang -O0 for example will crash, but clang -O1 will reuse the buffer1 memory for buffer2 and both addresses will be the same. In other words, buffer1 has been "freed" in a sense when the scope exits.

    GCC on the other hand will do this optimization even at -O0.