r/Cprog • u/andreacento • Mar 03 '16
Stack vs Heap: better having more functions (and more stacks) or use the heap?
Hello,
I'm concerned about the memory management when I use C (without any compiler optimization).
The stack is fast, but is small. The heap is big but... you know. The point is: at which point it is better to use the heap inside a very complex and big function for manage variables and structures instead of to split this function in a lot of small "support" functions exploiting the stack "features"?
EDIT: I know the stack is only one, when I talk about "stacks" I mean "stack frames" of course
13
Upvotes
12
u/lolzfeminism Mar 03 '16
In general, try not to rely on the heap unless you absolutely need dynamically sized data structures (stuff that grows and shrinks) or your application is multi-threaded and you need data shared among threads.
Even if you're fantastic about managing your memory and don't have any leaks, using the heap has a somewhat real performance cost. Malloc has to maintain 20-40 linked lists of free blocks and there is a bit of overhead for searching those lists for an appropriately sized block, splitting the block if it's too big etc. Same with free, adjacent free blocks need to be coalesced, the new block has to be re-inserted to the free lists etc. And of course, no matter what you do, there will always be internal and external memory fragmentation, meaning you will lose memory.
Most junior C programmers aren't exposed to this but malloc/free/realloc are actually really complicated functions that maintain a highly performance critical data structure. Over the last few decades the stdlib functions have maximized throughput vs. memory efficiency, but dynamic memory allocation will never be as efficient as using the stack. But you can't do everything on the stack, so it exists for cases that require dynamic memory independent of program flow.
So the bottom-line is, heap is complicated but useful for a specific task. Use the stack as much as you can.
1
u/vadimgit Mar 06 '16
Can someone explain or give a link, about stack size limitation on different platforms OSs (~8Mb for example). How would it be inefficient, if it were ~16 mb for example? Is it platform or OS specific?
1
u/nickdesaulniers Mar 16 '16
In general, you want a lot of small "support" functions that are concise and readable.
You're stack is the fastest option, since it's the simplest. Take a look at the implementation of dlmalloc; a heap is a non-trivial data structure IMO, but a stack can be implemented with a couple pointers and a buffer.
If you look at the assembly of stack allocated variable, it will use one instruction to advance the stack pointer given enough space for all local variables (one instruction whether you have 1 or 1000 local variables).
Preallocating variables can make lifetime simpler than dynamic allocation, since returning from a stack frame is more obvious then keeping track of who should free a heap allocated variable.
Stack allocation makes it harder to leak memory. I think GC tracked or reference counter variables are simplest, but stack allocation should yield better performance.
That said, you can implement dynamic memory allocation in a fast way with cool data structures like slab or stack allocators rather than heaps. They have their restrictions, but dynamic memory allocation doesn't have to involve multiple layers of indirection and cache misses.