Is it possible to free memory allocated by C's alloca() explicitly, before the current function exits? If so,how?
-
Could you explain your motivation? Why would you want to free the allocated space before returning? – Motti Dec 07 '08 at 20:22
8 Answers
From http://www.gnu.org/software/libc/manual/html_mono/libc.html#Variable-Size-Automatic:
Allocating a block with
alloca
is an explicit action; you can allocate as many blocks as you wish, and compute the size at run time. But all the blocks are freed when you exit the function that alloca was called from, just as if they were automatic variables declared in that function. There is no way to free the space explicitly.

- 172,675
- 36
- 177
- 197
It is possible, but there is no pre-written function to do it. You'd have to delve into your compiler's implementation of alloca() to figure out what it is doing, then write your own freea(). Since every compiler does alloca() differently, you'd have to rewrite your freea() for each compiler.
But I find it hard to believe this would be worth the trouble. Just use malloc/free if you need to explicitly free it - those functions are usually heavily optimized. Take advantage of them.

- 4,277
- 1
- 23
- 28
-
10One portable implementation is "void freea(void *p) {} // Just fake it". – paxdiablo Nov 12 '08 at 06:49
-
1Um, no. you can't move the stack pointer without getting corruption, and you can't relocate items on the stack because their addresses may be stored elsewhere. The reason free/malloc work is that they have full control of their heap space. – SquareCog Nov 12 '08 at 19:00
-
10I've implemented alloca(), and yes you can do a freea(). You won't be relocating items any more than alloca() does - locals with their address taken are necessarily before the alloca'd space. You shouldn't leave dangling pointers into freea'd space anyway, any more than you can for free'd space. – Walter Bright Nov 12 '08 at 22:33
-
Some implementations go to the heap if the allocation is large. I know Microsoft's does. – jww Sep 23 '16 at 00:58
-
1*I've implemented alloca(), and yes you can do a freea()* - oh, really? `a=alloca(asize);b=alloca(bsize);` could you please describe what a `freea(a);` call would do? – tevemadar Apr 16 '20 at 07:30
-
@tevemadar Presumably, it'd shrink the current stack frame to how it was before `*a` was allocated, freeing both `*a` and what came after it (`*b`). – Petr Skocik Oct 14 '20 at 23:05
Using C99 you can achieve the same thing using a Variable Length Array. Just declare the VLA in a new scope; it will automatically be freed when the scope exits.
For example:
int some_function(int n) {
// n has the desired length of the array
...
{ // new scope
int arr[n]; // instead of int *arr = alloca(n*sizeof(int));
// do stuff with array
}
// function continues with arr deallocated
...
}

- 9,060
- 14
- 61
- 123
This would be useful for continuation passing style (CPS), rather a realloca.
You could call a function which alloca'd and manipulated a string on the top of the stack, before shrinking the stack back down to the length of the string and calling the next function.
There's no conceptual reason why there couldn't be an freea(), which would be a nop for anything but the topmost entry on the stack.

- 42,671
- 44
- 178
- 308
You are allocating on the stack with alloca(); If something else happened afterwards (and you can't control it without writing everything in assembly), you can't just shrink the stack back. So until you leave the stack frame of your function, this is impossible.
This is also why you can really mess things up if you overflow the allocated buffer. You can start overwriting addresses of code your function returns to, causing it to jump elsewhere, all kinds of horrid stuff. Be careful!
Malloc works on the heap, so that's why it is much more flexible in what it can do.

- 19,421
- 8
- 49
- 63
No, because it's allocated on the stack along with the local variables. If you want memory that you can explicitly free, use one of the dynamic memory allocation functions.
There's no hybrid that allows you to explicitly free AND have it automatically free on function exit as well, at least not in the standard.

- 854,327
- 234
- 1,573
- 1,953
Yes, but it depends on the implementation of alloca(). A reasonable and simple implementation of alloca() is that the newly allocated block placed on top of stack by adjusting the stack pointer. Therefore to free this memory we only need to do a negative allocation (but you need to study the real implementation of alloca()), let's verify it by taking the following non-portable code for example:
#include <stdio.h>
#include <alloca.h>
int main()
{
unsigned long p0, p1, p2;
p0=(unsigned long)alloca(0);
p1=(unsigned long)alloca((size_t) 0x1000);
p2=(unsigned long)alloca((size_t)-0x1000);
printf( "p0=%lX, p1=%lX, p2=%lX\n", p0, p1, p2 );
return 0;
}
On an old x64 machine with clang 2.9, a sample output is:
p0=7FFF2C75B89F, p1=7FFF2C75A89F, p2=7FFF2C75B89F
So we know the implementation does not validate the argument -0x1000, otherwise the unsigned value will be a very large integer. Stack pointer was originally 0x...B89F; since this stack grows upward alloca(0x1000) therefore change the stack pointer up to (0x...B89F - 0x1000) = 0x...A89F. After the negative allocation (0xA89F - (-0x1000)) the stack pointer went back to 0x...B89F.
However, with gcc 4.8.3, a sample output is:
p0=7FFFA3E27A90, p1=7FFFA3E26A80, p2=7FFFA3E27A70
In /usr/include/alloca.h we found:
#ifdef __GNUC__
# define alloca(size) __builtin_alloca (size)
#endif /* GCC. */
So we know that the builtin alloca function provided by gcc 4.8.3 did similar thing except it allocate extra 0x10 bytes as a safety margin. When doing negative allocation it still assumes it grows upward and therefore tried to reserve 0x10 extra bytes (- 0x10) so p2= 0x...6A80 - (-0x1000) - 0x10 = 0x...7A70. So, be extra careful.

- 261
- 3
- 11
You don't need to write any custom freea(...)
kind of function, nor use VLA.
Memory allocated on the stack can be easily freed in both C and C++ (C++ doesn't support VLAs).
The alloca(...)
allocates on the stack, right? This means the memory is going to be deallocated when it goes out of scope... so just use scopes!
#include <alloca.h>
int main()
{
{
void* ptr = alloca(1024);
// do your stuff
} // memory is deallocated here
return 0;
}
As you can see from the godbolt online compiler, the assembly (with no optimization) does the right thing: https://godbolt.org/z/Gn5YMa