开发者

In which cases is alloca() useful?

Why would you ever want to use alloca() when you could always allocate a fixed size buffer on the s开发者_如何学Ctack large enough to fit all uses? This is not a rhetorical question...


It could be useful if the size of the buffer varies at runtime, or if you only sometimes need it: this would use less stack space overall than a fixed-size buffer in each call. Particularly if the function is high up the stack or recursive.


You might want to use it if there's no way to know the maximum size you might need at compile time.

Whether you should is another question - it's not standard, and there's no way to tell whether it might cause a stack overflow.


In which cases is alloca() useful?

The only time I ever saw alloca being used was in Open Dynamics Engine. AFAIK they were allocating HUGE matrices with it (so compiled program could require 100MB stack), which were automatically freed when function returns (looks like smartpointer ripoff to me). This was quite a while ago.

Although it was probably much faster than new/malloc, I still think it was a bad idea. Instead of politely running out of RAM program could crash with stack overflow (i.e. misleading) when scene became too complex to handle. Not a nice behavior, IMO, especially for physics engine, where you can easily expect someone to throw few thousands bricks into scene and see what happens when they all collide at once. Plus you had to set stack size manually - i.e. on system with more RAM, program would be still limited by stack size.

a fixed size buffer on the stack large enough to fit all uses? This is not a rhetorical question...

If you need fixed-size buffer for all uses, then you could as well put it into static/global variable or use heap memory.


Using alloca() may be reasonable when you are unable to use malloc() (or new in C++, or another memory allocator) reliably, or at all, but you can assume there's more space available on your stack - that is, when you can't really do anything else.

For example, in glibc's segfault.c, we have:

 /* This function is called when a segmentation fault is caught.  The system
    is in an unstable state now.  This means especially that malloc() might
    not work anymore.  */
static void
catch_segfault (int signal, SIGCONTEXT ctx)
{
    void **arr;

    /* ... */

    /* Get the backtrace.  */
    arr = alloca (256 * sizeof (void *));

    /* ... */
}


Never - it's not part of C++, and not useful in C. However, you cannot allocate "a static buffer on the stack" - static buffers are allocated at compile time, and not on the stack.

The point of alloca() is of course that it is not fixed sized, it is on the stack, and that it is freed automatically when a function exits. Both C++ and C have better mechanisms to handle this.


The alloca() function is virtually never needed; for memory allocation purposes, you can use malloc()/free() in C (or one of the collection of possibilities in C++) and achieve pretty much the same practical effect. This has the advantage of coping better with smaller stack sizes.

However I have seen[1] one legit (if hacky!) use of it: for detecting potential stack overflow on Windows; if the allocation (of the amount of slop space you wanted to access) failed, you were out but had enough room to recover gracefully. It was wrapped in __try/__except so that it didn't crash, and needed extra assembler tricks to avoid gcc-induced trouble. As I said, a hack. But a clever one that is the only valid use for alloca() that I've ever seen.

But don't do that. Better to write the code to not need such games.


[1] It was in Tcl 8.4 (and possibly earlier versions of Tcl). It was removed in later versions. Later versions removed it because it was finicky, very tricky and deeply troubling. 8.6 uses a stackless implementation of the execution engine instead of that sort of funkiness.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜