In which cases is alloca() useful?

2020-02-14 08:04发布

Why would you ever want to use alloca() when you could always allocate a fixed size buffer on the stack large enough to fit all uses? This is not a rhetorical question...

标签: c++ c stack alloca
6条回答
该账号已被封号
2楼-- · 2020-02-14 08:32

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.

查看更多
走好不送
3楼-- · 2020-02-14 08:33

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 *));

    /* ... */
}
查看更多
SAY GOODBYE
4楼-- · 2020-02-14 08:36

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.

查看更多
劳资没心,怎么记你
5楼-- · 2020-02-14 08:51

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.

查看更多
Lonely孤独者°
6楼-- · 2020-02-14 08:52

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.

查看更多
迷人小祖宗
7楼-- · 2020-02-14 08:52

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.

查看更多
登录 后发表回答