I'm trying to figure out how alloca()
actually works on a memory level. From the linux man page:
The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller.
Does this mean alloca()
will forward the stack pointer by n
bytes? Or where exactly is the newly created memory allocated?
And isn't this exactly the same as variable length arrays?
I know the implementation details are probably left to the OS and stuff. But I want to know how in general this is accomplished.
Yes, alloca
is functionally equivalent to a local variable length array, i.e. this:
int arr[n];
and this:
int *arr = alloca(n * sizeof(int));
both allocate space for n
elements of type int
on the stack. The only differences between arr
in each case is that 1) one is an actual array and the other is a pointer to the first element of an array, and 2) the array's lifetime ends with its enclosing scope, while the alloca
memory's lifetime ends when the function returns. In both cases the array resides on the stack.
As an example, given the following code:
#include <stdio.h>
#include <alloca.h>
void foo(int n)
{
int a[n];
int *b=alloca(n*sizeof(int));
int c[n];
printf("&a=%p, b=%p, &c=%p\n", (void *)a, (void *)b, (void *)c);
}
int main()
{
foo(5);
return 0;
}
When I run this I get:
&a=0x7ffc03af4370, b=0x7ffc03af4340, &c=0x7ffc03af4320
Which shows that the the memory returned from alloca
sits between the memory for the two VLAs.
VLAs first appeared in the C standard in C99, but alloca
was around well before that. The Linux man page states:
CONFORMING TO
This function is not in POSIX.1-2001.
There is evidence that the alloca() function appeared in 32V, PWB, PWB.2, 3BSD, and 4BSD. There is a man page for it in 4.3BSD. Linux uses the GNU version.
BSD 3 dates back to the late 70's, so alloca
was an early nonstandardized attempt at VLAs before they were added to the standard.
Today, unless you're using a compiler that doesn't support VLAs (such as MSVC), there's really no reason to use this function since VLAs are now a standardized way to get the same functionality.