Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is reasonable indicative size when it is better to go from stack to heap? [closed]

Is

WCHAR bitmapPathBuffer[512]

ok for stack allocation? or it is better to use heap for this size? What is reasonable indicative size when it is better to go from stack to heap... all says "is depens" but our brains need some limits to orients.

like image 944
Brans Ds Avatar asked Jul 14 '14 08:07

Brans Ds


4 Answers

You might want to check your system's default stack size, and consider whatever use your application makes of recursion, to arrive at some reasonable threshold.

Anyway, for typical desktop PCs I'd say ~100kb was reasonable to put on the stack for function that won't be invoked recursively without any unusual considerations (I had to revise that downwards after seeing how restrictive Windows was below). You may be able to go an order of magnitude more or less on specific systems but it's around that point you'd start to care about checking your system limits.

If you find you're doing that in many functions, you'd better think carefully about whether those functions could be called from each other, or just allocate dynamically (preferably implicitly via use of vector, string etc.) and not worry about it.

The 100kb guideline is based on these default stack size numbers ripped from the 'net:

platform    default size    # bits  # digits
    ===============================================================
SunOS/Solaris   8172K bytes <=39875 <=12003 (Shared Version)
Linux       8172K bytes <=62407 <=18786
Windows     1024K bytes <=10581 <=3185  (Release Version)
cygwin      2048K bytes <=3630  <=1092
like image 97
Tony Delroy Avatar answered Oct 06 '22 07:10

Tony Delroy


As others have said, the answer to this question is dependent on the system on which you are running. In order to come to a sensible answer, you need to know:

  • The default stack size. This might be different for threads other than the main thread(!), or if you're using closures or a third-party threading or coroutine library.
  • Whether the system stack is dynamically resized. On some systems, the stack can grow automatically up to a point.
  • On some platforms (e.g. ARM or PowerPC-based systems) there is a “red zone”. If you are in a leaf function (one that calls no other functions), if your stack usage is less than the size of the red zone, the compiler can generate more efficient code.

As a general rule I'd agree with the other respondents that on a desktop system, 16–64KB or so is a reasonable limit, but even that depends on things like recursion depth. Certainly, large stack frames are a code smell and should be investigated to make sure they're necessary.

In particular, it's well worth contemplating the lengths of any buffers allocated on the stack… are they really large enough for any conceivable input? And are you checking that at runtime to avoid overrun? e.g. In your example, are you sure that bitmapPathBuffer is never longer than 512 WCHARs in length? If you don't know the maximum length for certain, the heap may be better. Even then, if it's an adversarial environment, you may care to put a large upper bound on it to avoid attacks involving memory exhaustion.

like image 37
al45tair Avatar answered Oct 06 '22 06:10

al45tair


Answer is really "it depends".

If you have many such variables defined, or if you do relatively large stack allocations in your function and in functions this one calls, then it is possible that you will have stack overflow.

Typical default stack size for Win32 executable is 1MB. If you allocate more than that, you are in trouble and should change largest allocations to be on heap.

I would follow simple rule - if your allocations are more than say 16 - 64KB, then allocate on heap. Otherwise, it should be ok to allocate on stack.

like image 2
mvp Avatar answered Oct 06 '22 05:10

mvp


Modern compilers under normal circumstances use stack size of about 1 megabyte. So 1 KB is not a problem for a simple program.

If the program is very complex, other functions in the call chain also use large portions of the stack, your current function is very deep in the call stack, etc., then you better avoid large automatic variables.

If you use recursion, then you should carefully consider how deep it can be.

If you write a function that will be used in other projects or by other people, then you never know whether it can be called in a recursive function or deep in the stack. So it's usually a good idea to avoid large automatic variables in this case.

like image 2
Alexander Gelbukh Avatar answered Oct 06 '22 07:10

Alexander Gelbukh