On the use and abuse of alloca

风流意气都作罢 提交于 2019-11-28 23:11:03
Chris Eberle

Well first of all, even though there is a lot of virtual memory doesn't mean your process will be allowed to fill it. On *nix there are stack size limits, whereas the heap is a lot more forgiving.

If you're only going to be allocating a few hundred / thousand bytes, sure go ahead. Anything beyond that is going to depend on what limits (ulimit) are in place on any given system, and that's just a recipe for disaster.

Why is the use of alloca() not considered good practice?

On my development box at work (Gentoo) I have a default stack size limit of 8192 kb. That's not very big, and if alloca overflows the stack then the behavior is undefined.

I think you need to be a little bit careful in understanding what alloca actually is. Unlike malloc which goes to the heap, searches through buckets and linked lists of various buffers, alloca simply takes your stack register (ESP on x86) and moves it to create a "hole" on your thread's stack where you can store whatever you want. That's why it's uber-fast, just one (or few) assembly instruction.

So as others pointed out, it's not the "virtual memory" that you need to worry about but the size reserved for the stack. Although others limit themselves to "few hundred bytes", as long as you know your application and careful about it, we've allocated up to 256kb without any problems (default stack size, at least for visual studio, is 1mb and you can always increase it if you need to).

Also you really can't use alloca as a general purpose allocator (i.e. wrapping it inside another function) because whatever memory alloca allocates for you, that memory will be gone when the stack frame for current function is popped (i.e. when function exits).

I've also seen some people say that alloca is not completely cross-platform compatible, but if you are writing a specific application for a specific platform and you have the option of using alloca, sometimes it's the best option you have, as long as you understand the implications of increasing stack usage.

Firstly, it's because alloca memory is very hard to control. It's untyped, dies at the earliest opportunity, which makes it not very helpful. In addition, alloca has some unfortunate side effects, and those side effects are that regular stack variables now have to be dynamically indexed instead of constants, which can affect your performance in even basic operations accessing them and consumes register/stack space to store the dynamic offsets. This means that the real cost of using alloca isn't recorded in just the time it takes for the function to return. In addition, stack memory is very limited compared to heap memory- on Windows the stack limit is 8MB by default I believe, whereas the heap can be nearly the entire user address space. More than that, ultimately, whatever data you want to return has to be on the heap, so you may as well just use that as working space.

Steve Townsend

One point that has not been made afai can see is that the stack is often contiguous, while the heap is not. It's not in general true to say that the stack is as likely to run out of memory as the heap.

In C++, it's very common to see object instances declared as locals, which is sort of like an alloca but of structured memory rather than a block of N bytes - maybe you can think of this as a homage to your main point, which is that greater use of stack-based memory is a good idea. I'd sooner do that (declare an object instance as an RAII local) than use malloc (or alloca) in a C++ program. All those free calls to make exception-safe...

This generally assumes that the scope of the object is confined to this function and its called functions. If that's not the case then using stack-based memory is usually not a good idea anyway.

The windows stack does not grow - it's reserved size is set at link time, but the pages within this size will only be committed as needed. See http://msdn.microsoft.com/en-us/library/ms686774%28v=vs.85%29.asp. As the default reserved size is 1Mb, you could easily exceed this when using alloca().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!