tags:

views:

110

answers:

2

I've read quite a few places that alloca is obsolete and should not be used and Variable Length Arrays should be used instead.

My question is this: Is alloca completely replaceable by variable length arrays?

In my particular instance I have something that looks like this:

typedef struct { 
  int *value; 
  size_t size; 
  } some_type;

void SomeExternalFunction(some_type);

...

void foo(){
  //What I thought to do
  some_type bar;
  bar.value=alloca(sizeof(int)*10);
  SomeExternalFunction(bar);

  //what should be done without alloca
  some_type fizz;
  int tmp[10];
  fizz.value=tmp;
  SoemExternalFunction(fizz);
}

Am I missing something or is this an actual good use of alloca? Also assume for this example that for some reason I want for the value to be allocated on the stack

+3  A: 

There is an important difference between VLA's and alloca: The memory alloca() returns is valid as long as the current function persists. The lifetime of the memory occupied by a VLA is valid as long as the VLA's identifier remains in scope. You can alloca() memory in a loop for example and use the memory outside the loop, a VLA would be gone because the identifier goes out of scope when the loop terminates. This means, you can do this with alloca() and enough stack space:

typedef struct node { int data; struct node *next; };
void fun()
{
 struct node *n=0;
 int d;
 /* Now we are building a single-linked list on the stack! */
 while(d=get_something()) {
  struct node *x=alloca(sizeof(*x));
  x->next=n; 
  x->data=d;
  n=x;
 }
 do_something_with(n);
} // and the whole thing is deleted here..

You can't do this with VLAs.

Luther Blissett
FWIW: this would be a great answer to both [In which cases is alloca() useful?](http://stackoverflow.com/questions/3452434/in-which-cases-is-alloca-useful) and [What’s the difference between alloca(n) and char x\[n\]?](http://stackoverflow.com/questions/2614561/whats-the-difference-between-allocan-and-char-xn)
Shog9
This is a great answer regarding the difference, but you might also want to note that the behavior of `alloca` is essentially implementation-defined since it's not specified in any (current) standard.
R..
By the way, there **is** a way to do the same with VLAs: make the function recursive and call `do_something_with(n)` at the deepest level. :-) Actually I had a real-world use for this, which I haven't yet implemented: a lightweight implementation of `/lib/ld.so` which performs dynamic linking on the stack to avoid bringing `malloc` overhead into tiny programs that don't use it. At the end, it would unwind and discard all the dynamic linking data if and only if `libdl` has not been linked; otherwise it would call `_start` from the deepest level of recursion.
R..
@R: I remember reading somewhere that the *were/are* alloca's out there which deallocate when the current curly brace section is left. So it's probably a good idea to check the manual.
Luther Blissett
@R: Chicken Scheme uses a similar technique to perform its allocations: The program is compiled into a set of functions which call continuations with tail call exists, which means that all allocation could happen on the stack. The garbage collector would move the live objects to the heap when the stack is full and rewind the stack by performing a "return".
Luther Blissett
+1  A: 

alloca is completely replaceable by malloc and free. It's a little more work but unless you're very careful, it's essential. Nearly all code using alloca or C99 vla's is vulnerable to stack overflow attacks, and in many implementations, they can lead to privilege elevation. There's no portable way to know how large the stack is or how much stack space is left (or how much overhead beyond the requested size might be needed for the compiler's internal use or further function calls), so the only reasonable thing you can do to make vla's/alloca safe is impose extremely small artificial limits on the size of data you support (e.g. a few kb). At this point you might as well just be using plain non-variable-length automatic objects...

R..