alloca()
allocates memory from Stack rather than heap which is case in malloc()
. So, when I return from the routine the memory is freed. So, actually this solves my problem of freeing up of dynamically allocated memory. Freeing of memory allocated through malloc()
is a major headache and if somehow missed leads to all sorts memory problems.
Why is the use of alloca()
discouraged in spite of the above features?
I don't perceive such a consensus. Lots of strong pros; a few cons:
while
orfor
loop) or in several scopes, the memory accumulates per iteration/scope and is not released until the function exits: this contrasts with normal variables defined in the scope of a control structure (e.g.for {int i = 0; i < 2; ++i) { X }
would accumulatealloca
-ed memory requested at X, but memory for a fixed-sized array would be recycled per iteration).inline
functions that callalloca
, but if you force them then thealloca
will happen in the callers' context (i.e. the stack won't be released until the caller returns)alloca
transitioned from a non-portable feature/hack to a Standardised extension, but some negative perception may persistmalloc
's explicit controlmalloc
encourages thinking about the deallocation - if that's managed through a wrapper function (e.g.WonderfulObject_DestructorFree(ptr)
), then the function provides a point for implementation clean up operations (like closing file descriptors, freeing internal pointers or doing some logging) without explicit changes to client code: sometimes it's a nice model to adopt consistentlyWonderfulObject* p = WonderfulObject_AllocConstructor();
- that's possible when the "constructor" is a function returningmalloc
-ed memory (as the memory remains allocated after the function returns the value to be stored inp
), but not if the "constructor" usesalloca
WonderfulObject_AllocConstructor
could achieve this, but "macros are evil" in that they can conflict with each other and non-macro code and create unintended substitutions and consequent difficult-to-diagnose problemsfree
operations can be detected by ValGrind, Purify etc. but missing "destructor" calls can't always be detected at all - one very tenuous benefit in terms of enforcement of intended usage; somealloca()
implementations (such as GCC's) use an inlined macro foralloca()
, so runtime substitution of a memory-usage diagnostic library isn't possible the way it is formalloc
/realloc
/free
(e.g. electric fence)I know this question is tagged C, but as a C++ programmer I thought I'd use C++ to illustrate the potential utility of
alloca
: the code below (and here at ideone) creates a vector tracking differently sized polymorphic types that are stack allocated (with lifetime tied to function return) rather than heap allocated.All of the other answers are correct. However, if the thing you want to alloc using
alloca()
is reasonably small, I think that it's a good technique that's faster and more convenient than usingmalloc()
or otherwise.In other words,
alloca( 0x00ffffff )
is dangerous and likely to cause overflow, exactly as much aschar hugeArray[ 0x00ffffff ];
is. Be cautious and reasonable and you'll be fine.Actually, alloca is not guaranteed to use the stack. Indeed, the gcc-2.95 implementation of alloca allocates memory from the heap using malloc itself. Also that implementation is buggy, it may lead to a memory leak and to some unexpected behavior if you call it inside a block with a further use of goto. Not, to say that you should never use it, but some times alloca leads to more overhead than it releaves frome.
IMHO, alloca is considered bad practice because everybody is afraid of exhausting the stack size limit.
I learned much by reading this thread and some other links:
I use alloca mainly to make my plain C files compilable on msvc and gcc without any change, C89 style, no #ifdef _MSC_VER, etc.
Thank you ! This thread made me sign up to this site :)
One of the most memorable bugs I had was to do with an inline function that used
alloca
. It manifested itself as a stack overflow (because it allocates on the stack) at random points of the program's execution.In the header file:
In the implementation file:
So what happened was the compiler inlined
DoSomething
function and all the stack allocations were happening insideProcess()
function and thus blowing the stack up. In my defence (and I wasn't the one who found the issue, i had to go and cry to one of the senior developers when i couldn't fix it), it wasn't straightalloca
, it was one of ATL string conversion macros.So the lesson is - do not use
alloca
in functions that you think might be inlined.One issue is that it isn't standard, although it's widely supported. Other things being equal, I'd always use a standard function rather than a common compiler extension.