What are the stack and heap?
Where are they located physically in a computer's memory?
To what extent are they controlled by the OS or language run-time?
What is their scope?
What determines their sizes?
What makes one faster?
The stack is the memory set aside as scratch space for a thread of execution. When a function is called, a block is reserved on the top of the stack for local variables and some bookkeeping data. When that function returns, the block becomes unused and can be used the next time a function is called. The stack is always reserved in a LIFO (last in first out) order; the most recently reserved block is always the next block to be freed. This makes it really simple to keep track of the stack; freeing a block from the stack is nothing more than adjusting one pointer.
The heap is memory set aside for dynamic allocation. Unlike the stack, there's no enforced pattern to the allocation and deallocation of blocks from the heap; you can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time; there are many custom heap allocators available to tune heap performance for different usage patterns.
Each thread gets a stack, while there's typically only one heap for the application (although it isn't uncommon to have multiple heaps for different types of allocation).
To answer your questions directly:
To what extent are they controlled by the OS or language runtime?
The OS allocates the stack for each system-level thread when the thread is created. Typically the OS is called by the language runtime to allocate the heap for the application.
What is their scope?
The stack is attached to a thread, so when the thread exits the stack is reclaimed. The heap is typically allocated at application startup by the runtime, and is reclaimed when the application (technically process) exits.
What determines the size of each of them?
The size of the stack is set when a thread is created. The size of the heap is set on application startup, but can grow as space is needed (the allocator requests more memory from the operating system).
What makes one faster?
The stack is faster because the access pattern makes it trivial to allocate and deallocate memory from it (a pointer/integer is simply incremented or decremented), while the heap has much more complex bookkeeping involved in an allocation or deallocation. Also, each byte in the stack tends to be reused very frequently which means it tends to be mapped to the processor's cache, making it very fast. Another performance hit for the heap is that the heap, being mostly a global resource, typically has to be multi-threading safe, i.e. each allocation and deallocation needs to be - typically - synchronized with "all" other heap accesses in the program.
A clear demonstration:
Image source: vikashazrati.wordpress.com
Stack:
Stored in computer RAM just like the heap.
Variables created on the stack will go out of scope and are automatically deallocated.
Much faster to allocate in comparison to variables on the heap.
Implemented with an actual stack data structure.
Stores local data, return addresses, used for parameter passing.
Can have a stack overflow when too much of the stack is used (mostly from infinite or too deep recursion, very large allocations).
Data created on the stack can be used without pointers.
You would use the stack if you know exactly how much data you need to allocate before compile time and it is not too big.
Usually has a maximum size already determined when your program starts.
Heap:
Stored in computer RAM just like the stack.
In C++, variables on the heap must be destroyed manually and never fall out of scope. The data is freed with delete, delete[], or free.
Slower to allocate in comparison to variables on the stack.
Used on demand to allocate a block of data for use by the program.
Can have fragmentation when there are a lot of allocations and deallocations.
In C++ or C, data created on the heap will be pointed to by pointers and allocated with new or malloc respectively.
Can have allocation failures if too big of a buffer is requested to be allocated.
You would use the heap if you don't know exactly how much data you will need at run time or if you need to allocate a lot of data.
Responsible for memory leaks.
Example:
int foo()
{
char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
bool b = true; // Allocated on the stack.
if(b)
{
//Create 500 bytes on the stack
char buffer[500];
//Create 500 bytes on the heap
pBuffer = new char[500];
}//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
The most important point is that heap and stack are generic terms for ways in which memory can be allocated. They can be implemented in many different ways, and the terms apply to the basic concepts.
In a stack of items, items sit one on top of the other in the order they were placed there, and you can only remove the top one (without toppling the whole thing over).
The simplicity of a stack is that you do not need to maintain a table containing a record of each section of allocated memory; the only state information you need is a single pointer to the end of the stack. To allocate and de-allocate, you just increment and decrement that single pointer. Note: a stack can sometimes be implemented to start at the top of a section of memory and extend downwards rather than growing upwards.
In a heap, there is no particular order to the way items are placed. You can reach in and remove items in any order because there is no clear 'top' item.
Heap allocation requires maintaining a full record of what memory is allocated and what isn't, as well as some overhead maintenance to reduce fragmentation, find contiguous memory segments big enough to fit the requested size, and so on. Memory can be deallocated at any time leaving free space. Sometimes a memory allocator will perform maintenance tasks such as defragmenting memory by moving allocated memory around, or garbage collecting - identifying at runtime when memory is no longer in scope and deallocating it.
These images should do a fairly good job of describing the two ways of allocating and freeing memory in a stack and a heap. Yum!
To what extent are they controlled by the OS or language runtime?
As mentioned, heap and stack are general terms, and can be implemented in many ways. Computer programs typically have a stack called a call stack which stores information relevant to the current function such as a pointer to whichever function it was called from, and any local variables. Because functions call other functions and then return, the stack grows and shrinks to hold information from the functions further down the call stack. A program doesn't really have runtime control over it; it's determined by the programming language, OS and even the system architecture.
A heap is a general term used for any memory that is allocated dynamically and randomly; i.e. out of order. The memory is typically allocated by the OS, with the application calling API functions to do this allocation. There is a fair bit of overhead required in managing dynamically allocated memory, which is usually handled by the runtime code of the programming language or environment used.
What is their scope?
The call stack is such a low level concept that it doesn't relate to 'scope' in the sense of programming. If you disassemble some code you'll see relative pointer style references to portions of the stack, but as far as a higher level language is concerned, the language imposes its own rules of scope. One important aspect of a stack, however, is that once a function returns, anything local to that function is immediately freed from the stack. That works the way you'd expect it to work given how your programming languages work. In a heap, it's also difficult to define. The scope is whatever is exposed by the OS, but your programming language probably adds its rules about what a "scope" is in your application. The processor architecture and the OS use virtual addressing, which the processor translates to physical addresses and there are page faults, etc. They keep track of what pages belong to which applications. You never really need to worry about this, though, because you just use whatever method your programming language uses to allocate and free memory, and check for errors (if the allocation/freeing fails for any reason).
What determines the size of each of them?
Again, it depends on the language, compiler, operating system and architecture. A stack is usually pre-allocated, because by definition it must be contiguous memory. The language compiler or the OS determine its size. You don't store huge chunks of data on the stack, so it'll be big enough that it should never be fully used, except in cases of unwanted endless recursion (hence, "stack overflow") or other unusual programming decisions.
A heap is a general term for anything that can be dynamically allocated. Depending on which way you look at it, it is constantly changing size. In modern processors and operating systems the exact way it works is very abstracted anyway, so you don't normally need to worry much about how it works deep down, except that (in languages where it lets you) you mustn't use memory that you haven't allocated yet or memory that you have freed.
What makes one faster?
The stack is faster because all free memory is always contiguous. No list needs to be maintained of all the segments of free memory, just a single pointer to the current top of the stack. Compilers usually store this pointer in a special, fast register for this purpose. What's more, subsequent operations on a stack are usually concentrated within very nearby areas of memory, which at a very low level is good for optimization by the processor on-die caches.
(I have moved this answer from another question that was more or less a dupe of this one.)
The answer to your question is implementation specific and may vary across compilers and processor architectures. However, here is a simplified explanation.
Both the stack and the heap are memory areas allocated from the underlying operating system (often virtual memory that is mapped to physical memory on demand).
In a multi-threaded environment each thread will have its own completely independent stack but they will share the heap. Concurrent access has to be controlled on the heap and is not possible on the stack.
The heap
The heap contains a linked list of used and free blocks. New allocations on the heap (by new or malloc) are satisfied by creating a suitable block from one of the free blocks. This requires updating the list of blocks on the heap. This meta information about the blocks on the heap is also stored on the heap often in a small area just in front of every block.
As the heap grows new blocks are often allocated from lower addresses towards higher addresses. Thus you can think of the heap as a heap of memory blocks that grows in size as memory is allocated. If the heap is too small for an allocation the size can often be increased by acquiring more memory from the underlying operating system.
Allocating and deallocating many small blocks may leave the heap in a state where there are a lot of small free blocks interspersed between the used blocks. A request to allocate a large block may fail because none of the free blocks are large enough to satisfy the allocation request even though the combined size of the free blocks may be large enough. This is called heap fragmentation.
When a used block that is adjacent to a free block is deallocated the new free block may be merged with the adjacent free block to create a larger free block effectively reducing the fragmentation of the heap.
The stack
The stack often works in close tandem with a special register on the CPU named the stack pointer. Initially the stack pointer points to the top of the stack (the highest address on the stack).
The CPU has special instructions for pushing values onto the stack and popping them off the stack. Each push stores the value at the current location of the stack pointer and decreases the stack pointer. A pop retrieves the value pointed to by the stack pointer and then increases the stack pointer (don't be confused by the fact that adding a value to the stack decreases the stack pointer and removing a value increases it. Remember that the stack grows to the bottom). The values stored and retrieved are the values of the CPU registers.
If a function has parameters, these are pushed onto the stack before the call to the function. The code in the function is then able to navigate up the stack from the current stack pointer to locate these values.
When a function is called the CPU uses special instructions that push the current instruction pointer onto the stack, i.e. the address of the code executing on the stack. The CPU then jumps to the function by setting the instruction pointer to the address of the function called. Later, when the function returns, the old instruction pointer is popped off the stack and execution resumes at the code just after the call to the function.
When a function is entered, the stack pointer is decreased to allocate more space on the stack for local (automatic) variables. If the function has one local 32 bit variable four bytes are set aside on the stack. When the function returns, the stack pointer is moved back to free the allocated area.
Nesting function calls work like a charm. Each new call will allocate function parameters, the return address and space for local variables and these activation records can be stacked for nested calls and will unwind in the correct way when the functions return.
As the stack is a limited block of memory, you can cause a stack overflow by calling too many nested functions and/or allocating too much space for local variables. Often the memory area used for the stack is set up in such a way that writing below the bottom (the lowest address) of the stack will trigger a trap or exception in the CPU. This exceptional condition can then be caught by the runtime and converted into some kind of stack overflow exception.
Can a function be allocated on the heap instead of a stack?
No, activation records for functions (i.e. local or automatic variables) are allocated on the stack that is used not only to store these variables, but also to keep track of nested function calls.
How the heap is managed is really up to the runtime environment. C uses malloc and C++ uses new, but many other languages have garbage collection.
However, the stack is a more low-level feature closely tied to the processor architecture. Growing the heap when there is not enough space isn't too hard since it can be implemented in the library call that handles the heap. However, growing the stack is often impossible as the stack overflow only is discovered when it is too late; and shutting down the thread of execution is the only viable option.
In the following C# code
public void Method1()
{
int i = 4;
int y = 2;
class1 cls1 = new class1();
}
Here's how the memory is managed
Local Variables that only need to last as long as the function invocation go in the stack. The heap is used for variables whose lifetime we don't really know up front but we expect them to last a while. In most languages it's critical that we know at compile time how large a variable is if we want to store it on the stack.
Objects (which vary in size as we update them) go on the heap because we don't know at creation time how long they are going to last. In many languages the heap is garbage collected to find objects (such as the cls1 object) that no longer have any references.
In Java, most objects go directly into the heap. In languages like C / C++, structs and classes can often remain on the stack when you're not dealing with pointers.
More information can be found here:
The difference between stack and heap memory allocation « timmurphy.org
and here:
Creating Objects on the Stack and Heap
This article is the source of picture above: Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing - CodeProject
but be aware it may contain some inaccuracies.
Other answers just avoid explaining what static allocation means. So I will explain the three main forms of allocation and how they usually relate to the heap, stack, and data segment below. I also will show some examples in both C/C++ and Python to help people understand.
"Static" (AKA statically allocated) variables are not allocated on the stack. Do not assume so - many people do only because "static" sounds a lot like "stack". They actually exist in neither the stack nor the heap. They are part of what's called the data segment.
However, it is generally better to consider "scope" and "lifetime" rather than "stack" and "heap".
Scope refers to what parts of the code can access a variable. Generally we think of local scope (can only be accessed by the current function) versus global scope (can be accessed anywhere) although scope can get much more complex.
Lifetime refers to when a variable is allocated and deallocated during program execution. Usually we think of static allocation (variable will persist through the entire duration of the program, making it useful for storing the same information across several function calls) versus automatic allocation (variable only persists during a single call to a function, making it useful for storing information that is only used during your function and can be discarded once you are done) versus dynamic allocation (variables whose duration is defined at runtime, instead of compile time like static or automatic).
Although most compilers and interpreters implement this behavior similarly in terms of using stacks, heaps, etc, a compiler may sometimes break these conventions if it wants as long as behavior is correct. For instance, due to optimization a local variable may only exist in a register or be removed entirely, even though most local variables exist in the stack. As has been pointed out in a few comments, you are free to implement a compiler that doesn't even use a stack or a heap, but instead some other storage mechanisms (rarely done, since stacks and heaps are great for this).
I will provide some simple annotated C code to illustrate all of this. The best way to learn is to run a program under a debugger and watch the behavior. If you prefer to read python, skip to the end of the answer :)
// Statically allocated in the data segment when the program/DLL is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in the code
int someGlobalVariable;
// Statically allocated in the data segment when the program is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed from anywhere in this particular code file
static int someStaticVariable;
// "someArgument" is allocated on the stack each time MyFunction is called
// "someArgument" is deallocated when MyFunction returns
// scope - can be accessed only within MyFunction()
void MyFunction(int someArgument) {
// Statically allocated in the data segment when the program is first loaded
// Deallocated when the program/DLL exits
// scope - can be accessed only within MyFunction()
static int someLocalStaticVariable;
// Allocated on the stack each time MyFunction is called
// Deallocated when MyFunction returns
// scope - can be accessed only within MyFunction()
int someLocalVariable;
// A *pointer* is allocated on the stack each time MyFunction is called
// This pointer is deallocated when MyFunction returns
// scope - the pointer can be accessed only within MyFunction()
int* someDynamicVariable;
// This line causes space for an integer to be allocated in the heap
// when this line is executed. Note this is not at the beginning of
// the call to MyFunction(), like the automatic variables
// scope - only code within MyFunction() can access this space
// *through this particular variable*.
// However, if you pass the address somewhere else, that code
// can access it too
someDynamicVariable = new int;
// This line deallocates the space for the integer in the heap.
// If we did not write it, the memory would be "leaked".
// Note a fundamental difference between the stack and heap
// the heap must be managed. The stack is managed for us.
delete someDynamicVariable;
// In other cases, instead of deallocating this heap space you
// might store the address somewhere more permanent to use later.
// Some languages even take care of deallocation for you... but
// always it needs to be taken care of at runtime by some mechanism.
// When the function returns, someArgument, someLocalVariable
// and the pointer someDynamicVariable are deallocated.
// The space pointed to by someDynamicVariable was already
// deallocated prior to returning.
return;
}
// Note that someGlobalVariable, someStaticVariable and
// someLocalStaticVariable continue to exist, and are not
// deallocated until the program exits.
A particularly poignant example of why it's important to distinguish between lifetime and scope is that a variable can have local scope but static lifetime - for instance, "someLocalStaticVariable" in the code sample above. Such variables can make our common but informal naming habits very confusing. For instance when we say "local" we usually mean "locally scoped automatically allocated variable" and when we say global we usually mean "globally scoped statically allocated variable". Unfortunately when it comes to things like "file scoped statically allocated variables" many people just say... "huh???".
Some of the syntax choices in C/C++ exacerbate this problem - for instance many people think global variables are not "static" because of the syntax shown below.
int var1; // Has global scope and static allocation
static int var2; // Has file scope and static allocation
int main() {return 0;}
Note that putting the keyword "static" in the declaration above prevents var2 from having global scope. Nevertheless, the global var1 has static allocation. This is not intuitive! For this reason, I try to never use the word "static" when describing scope, and instead say something like "file" or "file limited" scope. However many people use the phrase "static" or "static scope" to describe a variable that can only be accessed from one code file. In the context of lifetime, "static" always means the variable is allocated at program start and deallocated when program exits.
Some people think of these concepts as C/C++ specific. They are not. For instance, the Python sample below illustrates all three types of allocation (there are some subtle differences possible in interpreted languages that I won't get into here).
from datetime import datetime
class Animal:
_FavoriteFood = 'Undefined' # _FavoriteFood is statically allocated
def PetAnimal(self):
curTime = datetime.time(datetime.now()) # curTime is automatically allocatedion
print("Thank you for petting me. But it's " + str(curTime) + ", you should feed me. My favorite food is " + self._FavoriteFood)
class Cat(Animal):
_FavoriteFood = 'tuna' # Note since we override, Cat class has its own statically allocated _FavoriteFood variable, different from Animal's
class Dog(Animal):
_FavoriteFood = 'steak' # Likewise, the Dog class gets its own static variable. Important to note - this one static variable is shared among all instances of Dog, hence it is not dynamic!
if __name__ == "__main__":
whiskers = Cat() # Dynamically allocated
fido = Dog() # Dynamically allocated
rinTinTin = Dog() # Dynamically allocated
whiskers.PetAnimal()
fido.PetAnimal()
rinTinTin.PetAnimal()
Dog._FavoriteFood = 'milkbones'
whiskers.PetAnimal()
fido.PetAnimal()
rinTinTin.PetAnimal()
# Output is:
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is steak
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is tuna
# Thank you for petting me. But it's 13:05:02.255000, you should feed me. My favorite food is milkbones
# Thank you for petting me. But it's 13:05:02.256000, you should feed me. My favorite food is milkbones
The Stack
When you call a function the arguments to that function plus some other overhead is put on the stack. Some info (such as where to go on return) is also stored there.
When you declare a variable inside your function, that variable is also allocated on the stack.
Deallocating the stack is pretty simple because you always deallocate in the reverse order in which you allocate. Stack stuff is added as you enter functions, the corresponding data is removed as you exit them. This means that you tend to stay within a small region of the stack unless you call lots of functions that call lots of other functions (or create a recursive solution).
The Heap
The heap is a generic name for where you put the data that you create on the fly. If you don't know how many spaceships your program is going to create, you are likely to use the new (or malloc or equivalent) operator to create each spaceship. This allocation is going to stick around for a while, so it is likely we will free things in a different order than we created them.
Thus, the heap is far more complex, because there end up being regions of memory that are unused interleaved with chunks that are - memory gets fragmented. Finding free memory of the size you need is a difficult problem. This is why the heap should be avoided (though it is still often used).
Implementation
Implementation of both the stack and heap is usually down to the runtime / OS. Often games and other applications that are performance critical create their own memory solutions that grab a large chunk of memory from the heap and then dish it out internally to avoid relying on the OS for memory.
This is only practical if your memory usage is quite different from the norm - i.e for games where you load a level in one huge operation and can chuck the whole lot away in another huge operation.
Physical location in memory
This is less relevant than you think because of a technology called Virtual Memory which makes your program think that you have access to a certain address where the physical data is somewhere else (even on the hard disc!). The addresses you get for the stack are in increasing order as your call tree gets deeper. The addresses for the heap are un-predictable (i.e implimentation specific) and frankly not important.
Others have answered the broad strokes pretty well, so I'll throw in a few details.
Stack and heap need not be singular. A common situation in which you have more than one stack is if you have more than one thread in a process. In this case each thread has its own stack. You can also have more than one heap, for example some DLL configurations can result in different DLLs allocating from different heaps, which is why it's generally a bad idea to release memory allocated by a different library.
In C you can get the benefit of variable length allocation through the use of alloca, which allocates on the stack, as opposed to alloc, which allocates on the heap. This memory won't survive your return statement, but it's useful for a scratch buffer.
Making a huge temporary buffer on Windows that you don't use much of is not free. This is because the compiler will generate a stack probe loop that is called every time your function is entered to make sure the stack exists (because Windows uses a single guard page at the end of your stack to detect when it needs to grow the stack. If you access memory more than one page off the end of the stack you will crash). Example:
void myfunction()
{
char big[10000000];
// Do something that only uses for first 1K of big 99% of the time.
}
Others have directly answered your question, but when trying to understand the stack and the heap, I think it is helpful to consider the memory layout of a traditional UNIX process (without threads and mmap()-based allocators). The Memory Management Glossary web page has a diagram of this memory layout.
The stack and heap are traditionally located at opposite ends of the process's virtual address space. The stack grows automatically when accessed, up to a size set by the kernel (which can be adjusted with setrlimit(RLIMIT_STACK, ...)). The heap grows when the memory allocator invokes the brk() or sbrk() system call, mapping more pages of physical memory into the process's virtual address space.
In systems without virtual memory, such as some embedded systems, the same basic layout often applies, except the stack and heap are fixed in size. However, in other embedded systems (such as those based on Microchip PIC microcontrollers), the program stack is a separate block of memory that is not addressable by data movement instructions, and can only be modified or read indirectly through program flow instructions (call, return, etc.). Other architectures, such as Intel Itanium processors, have multiple stacks. In this sense, the stack is an element of the CPU architecture.
What is a stack?
A stack is a pile of objects, typically one that is neatly arranged.
Stacks in computing architectures are regions of memory where data is added or removed in a last-in-first-out manner.
In a multi-threaded application, each thread will have its own stack.
What is a heap?
A heap is an untidy collection of things piled up haphazardly.
In computing architectures the heap is an area of dynamically-allocated memory that is managed automatically by the operating system or the memory manager library.
Memory on the heap is allocated, deallocated, and resized regularly during program execution, and this can lead to a problem called fragmentation.
Fragmentation occurs when memory objects are allocated with small spaces in between that are too small to hold additional memory objects.
The net result is a percentage of the heap space that is not usable for further memory allocations.
Both together
In a multi-threaded application, each thread will have its own stack. But, all the different threads will share the heap.
Because the different threads share the heap in a multi-threaded application, this also means that there has to be some coordination between the threads so that they don’t try to access and manipulate the same piece(s) of memory in the heap at the same time.
Which is faster – the stack or the heap? And why?
The stack is much faster than the heap.
This is because of the way that memory is allocated on the stack.
Allocating memory on the stack is as simple as moving the stack pointer up.
For people new to programming, it’s probably a good idea to use the stack since it’s easier.
Because the stack is small, you would want to use it when you know exactly how much memory you will need for your data, or if you know the size of your data is very small.
It’s better to use the heap when you know that you will need a lot of memory for your data, or you just are not sure how much memory you will need (like with a dynamic array).
Java Memory Model
The stack is the area of memory where local variables (including method parameters) are stored. When it comes to object variables, these are merely references (pointers) to the actual objects on the heap.
Every time an object is instantiated, a chunk of heap memory is set aside to hold the data (state) of that object. Since objects can contain other objects, some of this data can in fact hold references to those nested objects.
The stack is a portion of memory that can be manipulated via several key assembly language instructions, such as 'pop' (remove and return a value from the stack) and 'push' (push a value to the stack), but also call (call a subroutine - this pushes the address to return to the stack) and return (return from a subroutine - this pops the address off of the stack and jumps to it). It's the region of memory below the stack pointer register, which can be set as needed. The stack is also used for passing arguments to subroutines, and also for preserving the values in registers before calling subroutines.
The heap is a portion of memory that is given to an application by the operating system, typically through a syscall like malloc. On modern OSes this memory is a set of pages that only the calling process has access to.
The size of the stack is determined at runtime, and generally does not grow after the program launches. In a C program, the stack needs to be large enough to hold every variable declared within each function. The heap will grow dynamically as needed, but the OS is ultimately making the call (it will often grow the heap by more than the value requested by malloc, so that at least some future mallocs won't need to go back to the kernel to get more memory. This behavior is often customizable)
Because you've allocated the stack before launching the program, you never need to malloc before you can use the stack, so that's a slight advantage there. In practice, it's very hard to predict what will be fast and what will be slow in modern operating systems that have virtual memory subsystems, because how the pages are implemented and where they are stored is an implementation detail.
I think many other people have given you mostly correct answers on this matter.
One detail that has been missed, however, is that the "heap" should in fact probably be called the "free store". The reason for this distinction is that the original free store was implemented with a data structure known as a "binomial heap." For that reason, allocating from early implementations of malloc()/free() was allocation from a heap. However, in this modern day, most free stores are implemented with very elaborate data structures that are not binomial heaps.
You can do some interesting things with the stack. For instance, you have functions like alloca (assuming you can get past the copious warnings concerning its use), which is a form of malloc that specifically uses the stack, not the heap, for memory.
That said, stack-based memory errors are some of the worst I've experienced. If you use heap memory, and you overstep the bounds of your allocated block, you have a decent chance of triggering a segment fault. (Not 100%: your block may be incidentally contiguous with another that you have previously allocated.) But since variables created on the stack are always contiguous with each other, writing out of bounds can change the value of another variable. I have learned that whenever I feel that my program has stopped obeying the laws of logic, it is probably buffer overflow.
Simply, the stack is where local variables get created. Also, every time you call a subroutine the program counter (pointer to the next machine instruction) and any important registers, and sometimes the parameters get pushed on the stack. Then any local variables inside the subroutine are pushed onto the stack (and used from there). When the subroutine finishes, that stuff all gets popped back off the stack. The PC and register data gets and put back where it was as it is popped, so your program can go on its merry way.
The heap is the area of memory dynamic memory allocations are made out of (explicit "new" or "allocate" calls). It is a special data structure that can keep track of blocks of memory of varying sizes and their allocation status.
In "classic" systems RAM was laid out such that the stack pointer started out at the bottom of memory, the heap pointer started out at the top, and they grew towards each other. If they overlap, you are out of RAM. That doesn't work with modern multi-threaded OSes though. Every thread has to have its own stack, and those can get created dynamicly.
From WikiAnwser.
Stack
When a function or a method calls another function which in turns calls another function, etc., the execution of all those functions remains suspended until the very last function returns its value.
This chain of suspended function calls is the stack, because elements in the stack (function calls) depend on each other.
The stack is important to consider in exception handling and thread executions.
Heap
The heap is simply the memory used by programs to store variables.
Element of the heap (variables) have no dependencies with each other and can always be accessed randomly at any time.
Stack
Very fast access
Don't have to explicitly de-allocate variables
Space is managed efficiently by CPU, memory will not become fragmented
Local variables only
Limit on stack size (OS-dependent)
Variables cannot be resized
Heap
Variables can be accessed globally
No limit on memory size
(Relatively) slower access
No guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed
You must manage memory (you're in charge of allocating and freeing variables)
Variables can be resized using realloc()
In Short
A stack is used for static memory allocation and a heap for dynamic memory allocation, both stored in the computer's RAM.
In Detail
The Stack
The stack is a "LIFO" (last in, first out) data structure, that is managed and optimized by the CPU quite closely. Every time a function declares a new variable, it is "pushed" onto the stack. Then every time a function exits, all of the variables pushed onto the stack by that function, are freed (that is to say, they are deleted). Once a stack variable is freed, that region of memory becomes available for other stack variables.
The advantage of using the stack to store variables, is that memory is managed for you. You don't have to allocate memory by hand, or free it once you don't need it any more. What's more, because the CPU organizes stack memory so efficiently, reading from and writing to stack variables is very fast.
More can be found here.
The Heap
The heap is a region of your computer's memory that is not managed automatically for you, and is not as tightly managed by the CPU. It is a more free-floating region of memory (and is larger). To allocate memory on the heap, you must use malloc() or calloc(), which are built-in C functions. Once you have allocated memory on the heap, you are responsible for using free() to deallocate that memory once you don't need it any more.
If you fail to do this, your program will have what is known as a memory leak. That is, memory on the heap will still be set aside (and won't be available to other processes). As we will see in the debugging section, there is a tool called Valgrind that can help you detect memory leaks.
Unlike the stack, the heap does not have size restrictions on variable size (apart from the obvious physical limitations of your computer). Heap memory is slightly slower to be read from and written to, because one has to use pointers to access memory on the heap. We will talk about pointers shortly.
Unlike the stack, variables created on the heap are accessible by any function, anywhere in your program. Heap variables are essentially global in scope.
More can be found here.
Variables allocated on the stack are stored directly to the memory and access to this memory is very fast, and its allocation is dealt with when the program is compiled. When a function or a method calls another function which in turns calls another function, etc., the execution of all those functions remains suspended until the very last function returns its value. The stack is always reserved in a LIFO order, the most recently reserved block is always the next block to be freed. This makes it really simple to keep track of the stack, freeing a block from the stack is nothing more than adjusting one pointer.
Variables allocated on the heap have their memory allocated at run time and accessing this memory is a bit slower, but the heap size is only limited by the size of virtual memory. Elements of the heap have no dependencies with each other and can always be accessed randomly at any time. You can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time.
You can use the stack if you know exactly how much data you need to allocate before compile time, and it is not too big. You can use the heap if you don't know exactly how much data you will need at runtime or if you need to allocate a lot of data.
In a multi-threaded situation each thread will have its own completely independent stack, but they will share the heap. The stack is thread specific and the heap is application specific. The stack is important to consider in exception handling and thread executions.
Each thread gets a stack, while there's typically only one heap for the application (although it isn't uncommon to have multiple heaps for different types of allocation).
At run-time, if the application needs more heap, it can allocate memory from free memory and if the stack needs memory, it can allocate memory from free memory allocated memory for the application.
Even, more detail is given here and here.
Now come to your question's answers.
To what extent are they controlled by the OS or language runtime?
The OS allocates the stack for each system-level thread when the thread is created. Typically the OS is called by the language runtime to allocate the heap for the application.
More can be found here.
What is their scope?
Already given in top.
"You can use the stack if you know exactly how much data you need to allocate before compile time, and it is not too big. You can use the heap if you don't know exactly how much data you will need at runtime or if you need to allocate a lot of data."
More can be found in here.
What determines the size of each of them?
The size of the stack is set by OS when a thread is created. The size of the heap is set on application startup, but it can grow as space is needed (the allocator requests more memory from the operating system).
What makes one faster?
Stack allocation is much faster since all it really does is move the stack pointer. Using memory pools, you can get comparable performance out of heap allocation, but that comes with a slight added complexity and its own headaches.
Also, stack vs. heap is not only a performance consideration; it also tells you a lot about the expected lifetime of objects.
Details can be found from here.
OK, simply and in short words, they mean ordered and not ordered...!
Stack: In stack items, things get on the top of each-other, means gonna be faster and more efficient to be processed!...
So there is always an index to point the specific item, also processing gonna be faster, there is relationship between the items as well!...
Heap: No order, processing gonna be slower and values are messed up together with no specific order or index... there are random and there is no relationship between them... so execution and usage time could be vary...
I also create the image below to show how they may look like:
stack, heap and data of each process in virtual memory:
In the 1980s, UNIX propagated like bunnies with big companies rolling their own.
Exxon had one as did dozens of brand names lost to history.
How memory was laid out was at the discretion of the many implementors.
A typical C program was laid out flat in memory with
an opportunity to increase by changing the brk() value.
Typically, the HEAP was just below this brk value
and increasing brk increased the amount of available heap.
The single STACK was typically an area below HEAP which was a tract of memory
containing nothing of value until the top of the next fixed block of memory.
This next block was often CODE which could be overwritten by stack data
in one of the famous hacks of its era.
One typical memory block was BSS (a block of zero values)
which was accidentally not zeroed in one manufacturer's offering.
Another was DATA containing initialized values, including strings and numbers.
A third was CODE containing CRT (C runtime), main, functions, and libraries.
The advent of virtual memory in UNIX changes many of the constraints.
There is no objective reason why these blocks need be contiguous,
or fixed in size, or ordered a particular way now.
Of course, before UNIX was Multics which didn't suffer from these constraints.
Here is a schematic showing one of the memory layouts of that era.
A couple of cents: I think, it will be good to draw memory graphical and more simple:
Arrows - show where grow stack and heap, process stack size have limit, defined in OS, thread stack size limits by parameters in thread create API usually. Heap usually limiting by process maximum virtual memory size, for 32 bit 2-4 GB for example.
So simple way: process heap is general for process and all threads inside, using for memory allocation in common case with something like malloc().
Stack is quick memory for store in common case function return pointers and variables, processed as parameters in function call, local function variables.
Since some answers went nitpicking, I'm going to contribute my mite.
Surprisingly, no one has mentioned that multiple (i.e. not related to the number of running OS-level threads) call stacks are to be found not only in exotic languages (PostScript) or platforms (Intel Itanium), but also in fibers, green threads and some implementations of coroutines.
Fibers, green threads and coroutines are in many ways similar, which leads to much confusion. The difference between fibers and green threads is that the former use cooperative multitasking, while the latter may feature either cooperative or preemptive one (or even both). For the distinction between fibers and coroutines, see here.
In any case, the purpose of both fibers, green threads and coroutines is having multiple functions executing concurrently, but not in parallel (see this SO question for the distinction) within a single OS-level thread, transferring control back and forth from one another in an organized fashion.
When using fibers, green threads or coroutines, you usually have a separate stack per function. (Technically, not just a stack but a whole context of execution is per function. Most importantly, CPU registers.) For every thread there're as many stacks as there're concurrently running functions, and the thread is switching between executing each function according to the logic of your program. When a function runs to its end, its stack is destroyed. So, the number and lifetimes of stacks are dynamic and are not determined by the number of OS-level threads!
Note that I said "usually have a separate stack per function". There're both stackful and stackless implementations of couroutines. Most notable stackful C++ implementations are Boost.Coroutine and Microsoft PPL's async/await. (However, C++'s resumable functions (a.k.a. "async and await"), which were proposed to C++17, are likely to use stackless coroutines.)
Fibers proposal to the C++ standard library is forthcoming. Also, there're some third-party libraries. Green threads are extremely popular in languages like Python and Ruby.
I have something to share, although the major points are already covered.
Stack
Very fast access.
Stored in RAM.
Function calls are loaded here along with the local variables and function parameters passed.
Space is freed automatically when program goes out of a scope.
Stored in sequential memory.
Heap
Slow access comparatively to Stack.
Stored in RAM.
Dynamically created variables are stored here, which later requires freeing the allocated memory after use.
Stored wherever memory allocation is done, accessed by pointer always.
Interesting note:
Should the function calls had been stored in heap, it would had resulted in 2 messy points:
Due to sequential storage in stack, execution is faster. Storage in heap would have resulted in huge time consumption thus making the whole program execute slower.
If functions were stored in heap (messy storage pointed by pointer), there would have been no way to return to the caller address back (which stack gives due to sequential storage in memory).
Wow! So many answers and I don't think one of them got it right...
1) Where and what are they (physically in a real computer's memory)?
The stack is memory that begins as the highest memory address allocated to your program image, and it then decrease in value from there. It is reserved for called function parameters and for all temporary variables used in functions.
There are two heaps: public and private.
The private heap begins on a 16-byte boundary (for 64-bit programs) or a 8-byte boundary (for 32-bit programs) after the last byte of code in your program, and then increases in value from there. It is also called the default heap.
If the private heap gets too large it will overlap the stack area, as will the stack overlap the heap if it gets too big. Because the stack starts at a higher address and works its way down to lower address, with proper hacking you can get make the stack so large that it will overrun the private heap area and overlap the code area. The trick then is to overlap enough of the code area that you can hook into the code. It's a little tricky to do and you risk a program crash, but it's easy and very effective.
The public heap resides in it's own memory space outside of your program image space. It is this memory that will be siphoned off onto the hard disk if memory resources get scarce.
2) To what extent are they controlled by the OS or language runtime?
The stack is controlled by the programmer, the private heap is managed by the OS, and the public heap is not controlled by anyone because it is an OS service -- you make requests and either they are granted or denied.
2b) What is their scope?
They are all global to the program, but their contents can be private, public, or global.
2c) What determines the size of each of them?
The size of the stack and the private heap are determined by your compiler runtime options. The public heap is initialized at runtime using a size parameter.
2d) What makes one faster?
They are not designed to be fast, they are designed to be useful. How the programmer utilizes them determines whether they are "fast" or "slow"
REF:
https://norasandler.com/2019/02/18/Write-a-Compiler-10.html
https://learn.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-getprocessheap
https://learn.microsoft.com/en-us/windows/desktop/api/heapapi/nf-heapapi-heapcreate
A lot of answers are correct as concepts, but we must note that a stack is needed by the hardware (i.e. microprocessor) to allow calling subroutines (CALL in assembly language..). (OOP guys will call it methods)
On the stack you save return addresses and call → push / ret → pop is managed directly in hardware.
You can use the stack to pass parameters.. even if it is slower than using registers (would a microprocessor guru say or a good 1980s BIOS book...)
Without stack no microprocessor can work. (we can't imagine a program, even in assembly language, without subroutines/functions)
Without the heap it can. (An assembly language program can work without, as the heap is a OS concept, as malloc, that is a OS/Lib call.
Stack usage is faster as:
Is hardware, and even push/pop are very efficient.
malloc requires entering kernel mode, use lock/semaphore (or other synchronization primitives) executing some code and manage some structures needed to keep track of allocation.
Where and what are they (physically in a real computer's memory)?
ANSWER: Both are in RAM.
ASIDE:
RAM is like a desk and HDDs/SSDs (permanent storage) are like bookshelves. To read anything, you must have a book open on your desk, and you can only have as many books open as fit on your desk. To get a book, you pull it from your bookshelf and open it on your desk. To return a book, you close the book on your desk and return it to its bookshelf.
Stack and heap are names we give to two ways compilers store different kinds of data in the same place (i.e. in RAM).
What is their scope?
What determines the size of each of them?
What makes one faster?
ANSWER:
The stack is for static (fixed size) data
a. At compile time, the compiler reads the variable types used in your code.
i. It allocates a fixed amount of memory for these variables.
ii. This size of this memory cannot grow.
b. The memory is contiguous (a single block), so access is sometimes faster than the heap
c. An object placed on the stack that grows in memory during runtime beyond the size of the stack causes a stack overflow error
The heap is for dynamic (changing size) data
a. The amount of memory is limited only by the amount of empty space available in RAM
i. The amount used can grow or shrink as needed at runtime
b. Since items are allocated on the heap by finding empty space wherever it exists in RAM, data is not always in a contiguous section, which sometimes makes access slower than the stack
c. Programmers manually put items on the heap with the new keyword and MUST manually deallocate this memory when they are finished using it.
i. Code that repeatedly allocates new memory without deallocating it when it is no longer needed leads to a memory leak.
ASIDE:
The stack and heap were not primarily introduced to improve speed; they were introduced to handle memory overflow. The first concern regarding use of the stack vs. the heap should be whether memory overflow will occur. If an object is intended to grow in size to an unknown amount (like a linked list or an object whose members can hold an arbitrary amount of data), place it on the heap. As far as possible, use the C++ standard library (STL) containers vector, map, and list as they are memory and speed efficient and added to make your life easier (you don't need to worry about memory allocation/deallocation).
After getting your code to run, if you find it is running unacceptably slow, then go back and refactor your code and see if it can be programmed more efficiently. It may turn out the problem has nothing to do with the stack or heap directly at all (e.g. use an iterative algorithm instead of a recursive one, look at I/O vs. CPU-bound tasks, perhaps add multithreading or multiprocessing).
I say sometimes slower/faster above because the speed of the program might not have anything to do with items being allocated on the stack or heap.
To what extent are they controlled by the OS or language run-time?
ANSWER:
The stack size is determined at compile time by the compiler.
The heap size varies during runtime. (The heap works with the OS during runtime to allocate memory.)
ASIDE:
Below is a little more about control and compile-time vs. runtime operations.
Each computer has a unique instruction set architecture (ISA), which are its hardware commands (e.g. "MOVE", "JUMP", "ADD", etc.).
An OS is nothing more than a resource manager (controls how/when/ and where to use memory, processors, devices, and information).
The ISA of the OS is called the bare machine and the remaining commands are called the extended machine. The kernel is the first layer of the extended machine. It controls things like
determining what tasks get to use a processor (the scheduler),
how much memory or how many hardware registers to allocate to a task (the dispatcher), and
the order in which tasks should be performed (the traffic controller).
When we say "compiler", we generally mean the compiler, assembler, and linker together
The compiler turns source code into assembly language and passes it to the assembler,
The assembler turns the assembly language into machine code (ISA commands), and passes it to the linker
The linker takes all machine code (possibly generated from multiple source files) and combines it into one program.
The machine code gets passed to the kernel when executed, which determines when it should run and take control, but the machine code itself contains ISA commands for requesting files, requesting memory, etc. So the code issues ISA commands, but everything has to pass by the kernel.
The stack is essentially an easy-to-access memory that simply manages its items
as a - well - stack. Only items for which the size is known in advance can go onto the stack. This is the case for numbers, strings, booleans.
The heap is a memory for items of which you can’t predetermine the
exact size and structure. Since objects and arrays can be mutated and
change at runtime, they have to go into the heap.
Source: Academind
I feel most answers are very convoluted and technical, while I didn't find one that could explain simply the reasoning behind those two concepts (i.e. why people created them in the first place?) and why you should care. Here is my attempt at one:
Data on the Stack is temporary and auto-cleaning
Data on the Heap is permanent until manually deleted
That's it.
Still, for more explanations :
The stack is meant to be used as the ephemeral or working memory, a memory space that we know will be entirely deleted regularly no matter what mess we put in there during the lifetime of our program. That's like the memo on your desk that you scribble on with anything going through your mind that you barely feel may be important, which you know you will just throw away at the end of the day because you will have filtered and organized the actual important notes in another medium, like a document or a book. We don't care for presentation, crossing-outs or unintelligible text, this is just for our work of the day and will remember what we meant an hour or two ago, it's just our quick and dirty way to store ideas we want to remember later without hurting our current stream of thoughts. That's what people mean by "the stack is the scratchpad".
The heap however is the long-term memory, the actual important document that will we stored, consulted and depended on for a very long time after its creation. It consequently needs to have perfect form and strictly contain the important data. That why it costs a lot to make and can't be used for the use-case of our precedent memo. It wouldn't be worthwhile, or even simply useless, to take all my notes in an academic paper presentation, writing the text as calligraphy. However this presentation is extremely useful for well curated data. That's what the heap is meant to be. Well known data, important for the lifetime application, which is well controlled and needed at many places in your code. The system will thus never delete this precious data without you explicitly asking for it, because it knows "that's where the important data is!".
This is why you need to manage and take care of memory allocation on the heap, but don't need to bother with it for the stack.
Most top answers are merely technical details of the actual implementations of that concept in real computers.
So what to take away from this is that:
Unimportant, working, temporary, data just needed to make our functions and objects work is (generally) more relevant to be stored on the stack.
Important, permanent and foundational application data is (generally) more relevant to be stored on the heap.
This of course needs to be thought of only in the context of the lifetime of your program. Actual humanly important data generated by your program will need to be stored on an external file evidently. (Since whether it is the heap or the stack, they are both cleared entirely when your program terminates.)
PS: Those are just general rules, you can always find edge cases and each language comes with its own implementation and resulting quirks, this is meant to be taken as a guidance to the concept and a rule of thumb.
CPU stack and heap are physically related to how CPU and registers works with memory, how machine-assembly language works, not high-level languages themselves, even if these languages can decide little things.
All modern CPUs work with the "same" microprocessor theory: they are all based on what's called "registers" and some are for "stack" to gain performance. All CPUs have stack registers since the beginning and they had been always here, way of talking, as I know. Assembly languages are the same since the beginning, despite variations... up to Microsoft and its Intermediate Language (IL) that changed the paradigm to have a OO virtual machine assembly language. So we'll be able to have some CLI/CIL CPU in the future (one project of MS).
CPUs have stack registers to speed up memories access, but they are limited compared to the use of others registers to get full access to all the available memory for the processus. It why we talked about stack and heap allocations.
In summary, and in general, the heap is hudge and slow and is for "global" instances and objects content, as the stack is little and fast and for "local" variables and references (hidden pointers to forget to manage them).
So when we use the new keyword in a method, the reference (an int) is created in the stack, but the object and all its content (value-types as well as objects) is created in the heap, if I remember. But local elementary value-types and arrays are created in the stack.
The difference in memory access is at the cells referencing level: addressing the heap, the overall memory of the process, requires more complexity in terms of handling CPU registers, than the stack which is "more" locally in terms of addressing because the CPU stack register is used as base address, if I remember.
It is why when we have very long or infinite recurse calls or loops, we got stack overflow quickly, without freezing the system on modern computers...
C# Heap(ing) Vs Stack(ing) In .NET
Stack vs Heap: Know the Difference
Static class memory allocation where it is stored C#
What and where are the stack and heap?
https://en.wikipedia.org/wiki/Memory_management
https://en.wikipedia.org/wiki/Stack_register
Assembly language resources:
Assembly Programming Tutorial
Intel® 64 and IA-32 Architectures Software Developer Manuals
When a process is created then after loading code and data OS setup heap start just after data ends and stack to top of address space based on architecture
When more heap is required OS will allocate dynamically and heap chunk is always virtually contiguous
Please see brk(), sbrk() and alloca() system call in linux
Related
An experienced C++ user told me that I should strive for using heap variables, i.e.:
A* obj = new A("A");
as opposed to:
A obj("A");
Aside from all that stuff about using pointers being nice and flexible, he said it's better to put things on the heap rather than the stack (something about the stack being smaller than the heap?). Is it true? If so why?
NB: I know about issues with lifetime. Let's assume I have managed the lifetime of these variables appropriately. (i.e. the only criteria of concern is heap vs. stack storage with no lifetime concern)
Depending on the context we can consider heap or stack. Every thread gets a stack and the thread executes instructions by invoking functions. When a function is called, the function variables are pushed to stack. And when the function returns the stack rollbacks and memory is reclaimed. Now there is a size limitation for the thread local stack, it varies and can be tweaked to some extent. Considering this if every object is created on stack and the object requires large memory, then the stack space will exhaust resulting to stackoverflow error. Besides this if the object is to be accessed by multiple threads then storing such object on stack makes no sense.
Thus small variables, small objects who's size can be determine at compile time and pointers should be stored on stack. The concern of storing objects on heap or free store is, memory management becomes difficult. There are chances of memory leak, which is bad. Also if application tries to access an object which is already deleted, then access violation can happen which can cause application crash.
C++11 introduces smart pointers (shared, unique) to make memory management with heap easier. The actual referenced object is on heap but is encapsulation by the smart pointer which is always on the stack. Hence when the stack rollbacks during function return event or during exception the destructor of smart pointer deletes the actual object on heap. In case of shared pointer the reference count is maintained and the actually object is deleted when the reference count is zero.
http://en.wikipedia.org/wiki/Smart_pointer
There are no general rules regarding use of stack allocated vs heap allocated variables. There are only guidelines, depending on what you are trying to do.
Here are some pros and cons:
Heap Allocation:
Pros:
more flexible - in case you have a lot of information that is not available at compile-time
bigger in size - you can allocate more - however, it's not infinite, so at some point your program might run out of memory if allocations/deallocations are not handled correctly
Cons:
slower - dynamic allocation is usually slower than stack allocation
may cause memory fragmentation - allocating and deallocating objects of different sizes will make the memory look like Swiss cheese :) causing some allocations to fail if there is no memory block of the required size available
harder to maintain - as you know each dynamic allocation must be followed by a deallocation, which should be done by the user - this is error prone as there are a lot of cases where people forget to match every malloc() call with a free() call or new() with delete()
Stack allocation:
Pros:
faster - which is important mostly on embedded systems (I believe that for embedded there is a MISRA rule which forbids dynamic allocation)
does not cause memory fragmentation
makes the behavior of applications more deterministic - e.g. removes the possibility to run out of memory at some point
less error prone - as the user is not needed to handle deallocation
Cons:
less flexible - you have to have all information available at compile-time (data size, data structure, etc.)
smaller in size - however there are ways to calculate total stack size of an application, so running out of stack can be avoided
I think this captures a few of the pros and cons. I'm sure there are more.
In the end it depends on what your application needs.
The stack should be prefered to the heap, as stack allocated variables are automatic variables: their destruction is done automatically when the program goes out of their context.
In fact, the lifespan of object created on the stack and on the heap is different:
The local variables of a function or a code block {} (not allocated by new), are on the stack. They are automatically destroyed when you are returning from the function. (their destructors are called and their memory is freed).
But, if you need something an object to be used outside of the the function, you will have to allocate in on the heap (using new) or return a copy.
Example:
void myFun()
{
A onStack; // On the stack
A* onHeap = new A(); // On the heap
// Do things...
} // End of the function onStack is destroyed, but the &onHeap is still alive
In this example, onHeap will still have its memory allocated when the function ends. Such that if you don't have a pointer to onHeap somewhere, you won't be able to delete it and free the memory. It's a memory leak as the memory will be lost until the program end.
However if you were to return a pointer on onStack, since onStack was destroyed when exiting the function, using the pointer could cause undefined behaviour. While using onHeap is still perfectly valid.
To better understand how stack variables are working, you should search information about the call stack such as this article on Wikipedia. It explains how the variables are stacked to be used in a function.
It is always better to avoid using new as much as possible in C++.
However, there are times when you cannot avoid it.
For ex:
Wanting variables to exist beyond their scopes.
So it should be horses for courses really, but if you have a choice always avoid heap allocated variables.
The answer is not as clear cut as some would make you believe.
In general, you should prefer automatic variables (on the stack) because it's just plain easier. However some situations call for dynamic allocations (on the heap):
unknown size at compile time
extensible (containers use heap allocation internally)
large objects
The latter is a bit tricky. In theory, the automatic variables could get allocated infinitely, but computers are finite and worse all, most of the times the size of the stack is finite too (which is an implementation issue).
Personally, I use the following guideline:
local objects are allocated automatically
local arrays are deferred to std::vector<T> which internally allocates them dynamically
it has served me well (which is just anecdotal evidence, obviously).
Note: you can (and probably should) tie the life of the dynamically allocated object to that of a stack variable using RAII: smart pointers or containers.
C++ has no mention of the Heap or the Stack. As far as the language is concerned they do not exist/are not separate things.
As for a practical answer - use what works best - do you need fast - do you need guarantees. Application A might be much better with everything on the Heap, App B might fragment OS memory so badly it kills the machine - there is no right answer :-(
Simply put, don't manage your own memory unless you need to. ;)
Stack = Static Data allocated during compile time. (not dynamic)
Heap = Dyanamic Data allocated during run time. (Very dynamic)
Although pointers are on the Stack...Those pointers are beautiful because they open the doors for dynamic, spontaneous creation of data (depending on how you code your program).
(But I'm just a savage, so why does it matter what i say)
My question is pretty much basic and as the title says I want to know why heap memory came into picture . I am aware that heap memory supports dynamic memory allocation but why same could not be done through/within stack memory when both types of memory (static and heap) exist on RAM. Why it was needed to have separate segment of memory in process address space .While posting this question I came across several posts related to heap memory topic but so far I have checked does not answer my question rather is more about definition and behaviour of heap memory.
To be more clear on my question , Why there couldn't be one large stack memory which also handles dynamic memory allocation .As we know that dynamic memory is something which is created on the fly and can be freed up when required.Also there could be memory overrun or leak issue with dynamic memory allocation but can't it be done if there was one big stack memory as be it heap or stack if memory doesnt get freed up 'then it will definitely result in wastage even in case of program exit .Having said that when both memory resides on RAM then why there was requirement of different memory structure for handling memory.
With stack allocation there is a strict LIFO (last-in, first-out) policy for the lifetimes of allocated objects. That is, if you allocate object A, then object B, then object C, they will always be freed in the opposite order.
That's useful in a lot of cases, but there are also cases where you e.g. want object C to continue to exist after B and A have been destroyed. There's no way to do that with a stack, so to handle those cases the heap was introduced. It's harder to use correctly than stack allocation, but also more flexible/powerful.
Memory management, including heap like allocation and freeing of memory dates back to the 1950's. The "why" for this is because there was a need for it.
Note that the IBM 360 and later family of mainframes didn't have a stack. A caller provided save area for the registers was used instead, and simple programs just used a static array for that save area. More advanced programs could dynamically allocate memory as needed (depending on the OS), so in this case, heap memory existed without a stack.
In case you're wondering, interrupts were handle via a vector of pairs of words, one used to store the current state of the machine, the other initialized sometime beforehand with the state to handle that particular interrupt.
Other older mainframes and minicomputers didn't have a stack. In some cases, similar to the IBM 360 interrupt handler, the first word of a function was used to store the return address, and actual code started with the second word and returning was done using an indirect jump via the first word (such as CDC 3150, HP 2100).
Usually the stack and the heap exist in a large section of memory in RAM, where the heap starts at the beginning and grows forward and the stack starts at the top of the RAM and grows backward. Free memory in the middle can either be allocated to the stack or the heap depending on which is needed at runtime.
The main difference between the stack and the heap is how allocation is performed. The stack requires a last-in-first-out model of memory management, whereas the heap uses dynamic memory allocation, which is more flexible but more expensive.
Many useful programming patterns cannot be represented with the less expensive memory model of the stack. As a primary example, the memory for a growable array (a vector in C++) cannot be stored in the stack, since the amount of memory needed is unknown at compile time and may increase in the future, requiring a re-allocation.
The very simple answer to your question is that each memory type (stack and heap) must be managed by different mechanisms. The stack memory is basically managed by the compiler and is generally managed by code generated by the compiler based on your stack requirements in the code. Stack allocations are pushed and popped on a memory space set aside for that purpose. Heap memory comes and goes and the amount of memory allocated can change for each pass over the same set of code, thus the space requirements are not known at compile time.
From the computer systems stand point memory is memory. I have seen embedded systems where the embedded operating system allocates a large contiguous area of memory from the heap and points the stack pointer at that area. So effectively the stack memory is really in the heap space and is a single allocation of heap memory managed by the heap manager. Note that piece of memory is never going to be de-allocated during the running of the system.
So the short answer is that stack and heap memory have different requirements such that each "type" of memory has to be managed in a different way to satisfy those requirements.
Do you understand how the stack actually works?
When a function is called, memory for its local variables is allocated on the stack. When the function returns, the stack winds back, with the stack pointer going back to where it was before the function was called. Everything allocated on the stack by that function will be overwritten when the next function is called.
Without the heap, you wouldn't be able to have an object or array outlive the function call that creates it.
Also, part of the advantage of the stack is locality of memory. All of your local variables are very close to each other in memory, and as such are going to be on the same memory page. Dumping tons of large object allocations onto the stack would kill that locality.
The distinction between the heap and the stack is a bit arbitrary. Conceptually, stack memory just uses memory to represent the state of functions in the function call stack. Heap memory has a scope outside of functions in the function call stack. In theory, both of these could occupy the same section of memory in a program though. However, in practice they don't since the hardware and operating system are specialized for the two different uses.
Theoretically, a heap isn't necessary. Once the scope for objects isn't the function call frame, it becomes difficult to manage object lifetimes and memory though. Ownership of the object has to be passed higher in the call stack as functions exit, which generally means copying. So, it would imply a serious performance penalty.
One of the other issues is that objects ultimately need to be reclaimed. Since objects are laid out contiguously in stack memory, there would be gaps of various sizes in memory between dead objects and live objects. Essentially this would mean the dead memory isn't usable and leaked.
So, the primary reason for a heap is to effectively maintain memory that's outside the scope of a function call.
Stack memory is faster than heap memory, but at the cost of flexibility.
It's like creating files on a disk. You can create a lot of files occupying a lot of space. Later you can delete some of them. Part of the space is free again and can be used by another process. This mechanism is very useful, though sometimes you run into fragmentation problem. You can think of heap allocation as a similar thing. In contrast stack memory is usually much smaller, with very simple management (just moving a stack pointer), and cannot be manipulated like heap.
You can say stack and heap are required by CPU and OS design.
I recently dove into graphics programming and I noticed that many graphic engines (i.e Ogre), and many coders overall, prefer to initialize class instances dynamically. Here's an example from Ogre Basic Tutorial 1
//...
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
//...
ogreHead and headNode data members and methods are then referred to as ogreHead->blabla.
Why mess around with object pointers instead of plain objects?
BTW, I've also read somewhere that heap memory allocation is much slower than stack memory allocation.
Heap allocation is, inevitably much slower than stack allocation. More on "How much slower?" later. However, in many cases, the choice is "made for you", for several reasons:
Stack is limited. And if you run out, the application almost always gets terminated - there is no real good recovery, even printing an error message to say "I ran out of stack" may be hard...
Stack allocation "goes away" when you leave the function where the allocation was made.
Variability is much more well defined and easy to deal with. C++ does not cope with "variable length arrays" very well, and it's certainly not guaranteed to work in all compilers.
How much slower is heap over stack?
We'll get to "and does it matter" in a bit.
For a given allocation, stack allocation is simply a subtract operation [1], where at the very minimum new or malloc will be a function call, and probably even the most simple allocator will be several dozen instructions, in complex cases thousands [because memory has to be gotten from the OS, and cleared of it's previous content]. So anything from a 10x to "infinitely" slower, give or take. Exact numbers will depend on the exact system the code is running in, size of the allocation, and often "previous calls to the allocator" (e.g. a long list of "freed" allocations can make allocating a new object slower, because a good fit has to be searched for). And of course, unless you do the "ostrich" method of heap management, you also need to free the object and cope with "out of memory" which adds more code/time to the execution and complexity of the code.
With some reasonably clever programming, however, this can be mostly hidden - for example, allocating something that stays allocated for a long time, over the lifetime of the object, will be "nothing to worry about". Allocating objects from the heap for every pixel or every trianle in a 3D game would CLEARLY be a bad idea. But if the lifetime of the object is many frames or even the entire game, the time to allocate and free it will be nearly nothing.
Similarly, instead of doing 10000 individual object allocations, make one for 10000 objects. Object pool is one such concept.
Further, often the allocation time isn't where the time is spent. For example, reading a triangle list from a file from a disk will take much longer than allocating the space for the same triangle list - even if you allocate each single one!
To me, the rule is:
Does it fit nicely on the stack? Typically a few kilobytes is fine, many kilobytes not so good, and megabytes definitely not ok.
Is the number (e.g. array of objects) known, and the maximum such that you can fit it on the stack?
Do you know what the object will be? In other words abstract/polymorphic classes will probably need to be allocated on the heap.
Is its lifetime the same as the scope it is in? If not, use the heap (or stack further down, and pass it up the stack).
[1] Or add if stack is "grows towards high addresses" - I don't know of a machine which has such an architecture, but it is conceivable and I think some have been made. C certainly makes no promises as to which way the stack grows, or anything else about how the runtime stack works.
The scope of the stack is limited: it only exists within a function. Now, modern user-interfacing programs are usually event driven, which means that a function of yours is invoked to handle an event, and then that function must return in order for the program to continue running. So, if your event handler function wishes to create an object which will remain in existence after the function has returned, clearly, that object cannot be allocated on the stack of that function, because it will cease to exist as soon as the function returns. That's the main reason why we allocate things on the heap.
There are other reasons, too.
Sometimes, the exact size of a class is not known during compilation time. If the exact size of a class is not known, it cannot be created on the stack, because the compiler needs to have precise knowledge of how much space it needs to allocate for each item on the stack.
Furthermore, factory methods like whatever::createEntity() are often used. If you have to invoke a separate method to create an object for you, then that object cannot be created on the stack, for the reason explained in the first paragraph of this answer.
Why pointers instead of objects?
Because pointers help make things fast. If you pass an object by value, to another function, for example
shoot(Orge::Entity ogre)
instead of
shoot(Orge::Entity* ogrePtr)
If ogre isn't a pointer, what happens is you are passing the whole object into the function, rather than a reference. If the compiler doesn't optimize, you are left with an inefficient program. There are other reasons too, with the pointer, you can modify the passed in object (some argue references are better but that's a different discussion). Otherwise you would be spending too much time copying modified objects back and forth.
Why heap?
In some sense heap is a safer type of memory to access and allows you to safely reset/recover. If you call new and don't have memory, you can flag that as an error. If you are using the stack, there is actually no good way to know you have caused stackoverflow, without some other supervising program, at which point you are already in danger zone.
Depends on your application. Stack has local scope so if the object goes out of scope, it will deallocate memory for the object. If you need the object in some other function, then no real way to do that.
Applies more to OS, heap is comparatively much larger than stack, especially in multi-threaded application where each thread can have a limited stack size.
Well, I am sorry if this feels like a repetition of old questions, I have gone through several questions on Stack Overflow, the Modern Operating Systems Book by tanenbaum, and have still to clear my doubts regarding this.
First off, I would appreciate any book/resource that I should go through in more detail to better understand this structure. I fail to understand if these are concepts generally explained in OS books, or Programming Languages or Architecture books.
Before I ask my questions, I will list out my findings based on readings about stacks/heaps
Heap
Contains all Instance Variables, Dynamically Allocated (new/malloc), and Global Variables only
Does not use the data structure heap anymore, uses more complex structures
Access through memory locations, individual process responsible for memory allocated on it
Defragmentation, and allocation of memory is done by the OS (If yes or no, please answer my question on who manages the heap, os or runtime environ)
Shared among all threads within the process which have access to its reference
Stack
Contains all local variables only. (Pushed on at function call)
Uses an actual Stack Data Structure for operation
Faster to access due to contiguous nature
Now, For a few of my questions regarding the same.
Global Variables, where do they get allocated? (My belief is that they get allocated on the heap, If so, When do they get allocated, at runtime or compile time, and one further question, can this memory be cleared (as in using delete)? )
What is the structure of the heap? How is the heap organized (is it managed by the os or the run time environment (as set up by the C/C++ compiler) ).
Does the stack hold ONLY method, and their local variables?
Each application (Process) is given a separate heap, but if you exceed heap allocations, then does it mean that the os was not able to allocate more memory? (I am assuming lack of memory causes the OS to reallocate to avoid fragmentation)
The Heap is accessible from all threads within the process (I believe this to be true). If yes all threads can access Instance Variables, Dynamically allocated variables, global variables (If they have a reference to it)
Different processes, cannot access each others heap (even if they are passed the address)
A Stack overflow crashes
only the current thread
current process
all processes
In C/C++, does memory get allocated during run time on the stack for block variables within a function (For example, if a sub-block (eg. For loop) of code creates a new variable is that allocated during run-time on the stack (or the heap) or is it preallocated?) when are they removed (Block level scope, how is that maintained). My belief on this is, all additions to stack are made at runtime before the start of a block, whenever the end of that block is reached, all elements added till that point are pushed.
The CPU's support for the stack register is limited to a stack pointer that can be incremented (pop) and decremented (push) via normal access to memory. (Is this true?)
Last, are both stack, and heap structures generated by the OS/Runtime environment that exist on Main Memory (As an abstraction?)
I know this is a lot, and I appear to be very confused throughout, I would appreciate it if you could point me in the right direction to get these things cleared up!
Global variables are allocated in a static section of memory that's laid out at compile time. The values are initialized during startup before main is entered. The initialization may, of course, allocate on the heap (i.e. a statically allocated std::string will have the structure itself sit in the statically laid out memory, but the string data it contains is allocated on the heap during startup). These things are deleted during normal program shutdown. You can't free them before then, if you wish to, you may want to wrap the value in a pointer, and initialize the pointer on program startup.
The heap is managed by an allocator library. There's one that comes with the C runtime, but also custom ones like tcmalloc or jemalloc that you can use in place of the standard allocator. These allocator get large pages of memory from the OS using system calls, and then give you portions of these pages when you call malloc. The organization of the heap is somewhat complex and varies between allocators, you can look up how they work on their websites.
Yes-ish. Though you can use library functions like alloca to make a chunk of space on the stack, and use that for whatever you want.
Each process has a separate memory space, that is, it thinks it is all alone and no other process exists. Generally the OS will give you more memory if you ask for it, but it can also enforce limits (like ulimit on linux), at which time it can refuse to give you more memory. Fragmentation isn't an issue for the OS because it gives memory in pages. However fragmentation in your process may cause your allocator to ask for more pages, even if there's empty space.
Yes.
Yes, however there's generally OS specific ways to create shared-memory regions that multiple processes can access.
stack overflows doesn't crash anything itself, it causes memory values to be written in places that may hold other values, thus corrupting it. Acting on corrupted memory causes crashes. When your process accesses unmapped memory (see note below) it crashes, not just a thread, but the whole process. It would not affect other processes since their memory spaces are isolated. (This is not true in old operating systems like Windows 95, where all processes shared the same memory space).
In C++, stack-allocated objects are created when the block is entered, and destroyed when the block is exited. The actual space on the stack may be allocated less precisely though, but the construction and destruction will take place at those particular points.
The stack pointer on x86 processes can be arbitrarily manipulated. It's common for compilers to generate code that simply add the amount of space to the stack pointer, and then set the memory for values on the stack, instead of doing a bunch of push operations.
The stacks and heap of the process all live in the same memory space.
An overview of how memory is organized may be helpful:
You have physical memory which the kernel sees.
The kernel maps pages of physical memory to pages of virtual memory when a process asks for it.
A process operates in its own virtual memory space, ignorant of other processes on the system.
When a process starts, it puts sections of the executable (code, globals, etc) into some of these virtual memory pages.
The allocator requests pages from the process in order to satisfy malloc calls, this memory constitutes the heap.
when a thread starts (or the initial thread for the process), it asks the OS for a few pages that form the stack. (You can also ask your heap allocator, and use the space it gives you as a stack).
When the program is running, it can freely access to all memory in its address space, heap, stack, whatever.
When you attempt to access a region of your memory space that is not mapped, your program crashes. (more specifically, you get a signal from the OS, which you can choose to handle).
Stack overflows tend to cause your programs to access such unmapped regions, which is why stack overflows tend to crash your program.
Where global variables are allocated is actually system dependent. Some systems will place them statically in the binary, some will allocate them on the heap, some will allocate them on the stack. If a global variable is a pointer, you can delete the value it points to, but there is no way to clear that memory otherwise. Destructors for global variables will be called automatically when the application exits (well, maybe not with a SIGTERM)
I'm not positive, but I imagine it's managed by the operating system, specifically the kernel.
Yes, and only to a certain point. For instance, you can't do infinite recursion because values will (no pun intended) stack up. You'll wind up with a, wait for it, stack overflow (AHH, there it is, he said it!)
Some operating systems may impose a heap size limit through a separate process, but generally if you fail to allocate memory it's because there's no memory left.
All threads share a common heap, and so yes, they can all access global variables, dynamically allocated, etc..
Generally correct, though on some really bare-bones architectures this may not be true. For the most part, the OS executes the process in the context of a virtual table, so the pointer values you're using actually point to a different memory address than what they would appear to.
The current process, if by process you mean OS-level process.
I'm assuming that is correct, but I don't know myself.
This one's out of my wheelhouse.
Yes, sort of. As I mentioned before, most OSes use vtables to map process pointers to main memory. Also, consider paging to disk (swapping)
An experienced C++ user told me that I should strive for using heap variables, i.e.:
A* obj = new A("A");
as opposed to:
A obj("A");
Aside from all that stuff about using pointers being nice and flexible, he said it's better to put things on the heap rather than the stack (something about the stack being smaller than the heap?). Is it true? If so why?
NB: I know about issues with lifetime. Let's assume I have managed the lifetime of these variables appropriately. (i.e. the only criteria of concern is heap vs. stack storage with no lifetime concern)
Depending on the context we can consider heap or stack. Every thread gets a stack and the thread executes instructions by invoking functions. When a function is called, the function variables are pushed to stack. And when the function returns the stack rollbacks and memory is reclaimed. Now there is a size limitation for the thread local stack, it varies and can be tweaked to some extent. Considering this if every object is created on stack and the object requires large memory, then the stack space will exhaust resulting to stackoverflow error. Besides this if the object is to be accessed by multiple threads then storing such object on stack makes no sense.
Thus small variables, small objects who's size can be determine at compile time and pointers should be stored on stack. The concern of storing objects on heap or free store is, memory management becomes difficult. There are chances of memory leak, which is bad. Also if application tries to access an object which is already deleted, then access violation can happen which can cause application crash.
C++11 introduces smart pointers (shared, unique) to make memory management with heap easier. The actual referenced object is on heap but is encapsulation by the smart pointer which is always on the stack. Hence when the stack rollbacks during function return event or during exception the destructor of smart pointer deletes the actual object on heap. In case of shared pointer the reference count is maintained and the actually object is deleted when the reference count is zero.
http://en.wikipedia.org/wiki/Smart_pointer
There are no general rules regarding use of stack allocated vs heap allocated variables. There are only guidelines, depending on what you are trying to do.
Here are some pros and cons:
Heap Allocation:
Pros:
more flexible - in case you have a lot of information that is not available at compile-time
bigger in size - you can allocate more - however, it's not infinite, so at some point your program might run out of memory if allocations/deallocations are not handled correctly
Cons:
slower - dynamic allocation is usually slower than stack allocation
may cause memory fragmentation - allocating and deallocating objects of different sizes will make the memory look like Swiss cheese :) causing some allocations to fail if there is no memory block of the required size available
harder to maintain - as you know each dynamic allocation must be followed by a deallocation, which should be done by the user - this is error prone as there are a lot of cases where people forget to match every malloc() call with a free() call or new() with delete()
Stack allocation:
Pros:
faster - which is important mostly on embedded systems (I believe that for embedded there is a MISRA rule which forbids dynamic allocation)
does not cause memory fragmentation
makes the behavior of applications more deterministic - e.g. removes the possibility to run out of memory at some point
less error prone - as the user is not needed to handle deallocation
Cons:
less flexible - you have to have all information available at compile-time (data size, data structure, etc.)
smaller in size - however there are ways to calculate total stack size of an application, so running out of stack can be avoided
I think this captures a few of the pros and cons. I'm sure there are more.
In the end it depends on what your application needs.
The stack should be prefered to the heap, as stack allocated variables are automatic variables: their destruction is done automatically when the program goes out of their context.
In fact, the lifespan of object created on the stack and on the heap is different:
The local variables of a function or a code block {} (not allocated by new), are on the stack. They are automatically destroyed when you are returning from the function. (their destructors are called and their memory is freed).
But, if you need something an object to be used outside of the the function, you will have to allocate in on the heap (using new) or return a copy.
Example:
void myFun()
{
A onStack; // On the stack
A* onHeap = new A(); // On the heap
// Do things...
} // End of the function onStack is destroyed, but the &onHeap is still alive
In this example, onHeap will still have its memory allocated when the function ends. Such that if you don't have a pointer to onHeap somewhere, you won't be able to delete it and free the memory. It's a memory leak as the memory will be lost until the program end.
However if you were to return a pointer on onStack, since onStack was destroyed when exiting the function, using the pointer could cause undefined behaviour. While using onHeap is still perfectly valid.
To better understand how stack variables are working, you should search information about the call stack such as this article on Wikipedia. It explains how the variables are stacked to be used in a function.
It is always better to avoid using new as much as possible in C++.
However, there are times when you cannot avoid it.
For ex:
Wanting variables to exist beyond their scopes.
So it should be horses for courses really, but if you have a choice always avoid heap allocated variables.
The answer is not as clear cut as some would make you believe.
In general, you should prefer automatic variables (on the stack) because it's just plain easier. However some situations call for dynamic allocations (on the heap):
unknown size at compile time
extensible (containers use heap allocation internally)
large objects
The latter is a bit tricky. In theory, the automatic variables could get allocated infinitely, but computers are finite and worse all, most of the times the size of the stack is finite too (which is an implementation issue).
Personally, I use the following guideline:
local objects are allocated automatically
local arrays are deferred to std::vector<T> which internally allocates them dynamically
it has served me well (which is just anecdotal evidence, obviously).
Note: you can (and probably should) tie the life of the dynamically allocated object to that of a stack variable using RAII: smart pointers or containers.
C++ has no mention of the Heap or the Stack. As far as the language is concerned they do not exist/are not separate things.
As for a practical answer - use what works best - do you need fast - do you need guarantees. Application A might be much better with everything on the Heap, App B might fragment OS memory so badly it kills the machine - there is no right answer :-(
Simply put, don't manage your own memory unless you need to. ;)
Stack = Static Data allocated during compile time. (not dynamic)
Heap = Dyanamic Data allocated during run time. (Very dynamic)
Although pointers are on the Stack...Those pointers are beautiful because they open the doors for dynamic, spontaneous creation of data (depending on how you code your program).
(But I'm just a savage, so why does it matter what i say)