To clarify, this answer has incorrect information (thomas fixed his answer after comments, cool :) ). 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. The 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).