5

I was reading this article and saw this: "This article assumes that you already know and understand at least basically how the memory map in GNU/Linux system works, and specially the difference between memory statically allocated in the stack and memory dynamically allocated in the heap."

This confused me because I thought that stack and heap are dynamically allocated, meaning only allocated if necessary, and global variables and variables declared as "static" inside of a function are statically allocated, meaning always allocated.

For example, if I have

void f() { int x = 1; ... } 

the value 1 only gets put on the stack and the stack pointer only gets incremented if the function f() gets called. Likewise, if I have

void f() { int x = malloc(1 * sizeof(int)); ... } 

that heap memory only gets allocated if f() is called. However, if I have "int x = 1;" in the global section of the program or "static int x = 1;" within a function body, any time I run this program, that memory will be allocated in the data section with the value 1.

Am I wrong about any of this?

4
  • 2
    Static variables are never allocated on the stack. Commented Oct 10, 2015 at 17:43
  • Technically local variables doesn't have to be on the stack, there might not even be a stack. In fact, the C specification doesn't mention a stack in the context of local variables or arguments, it just specifies the scope and lifetime of local variables. Commented Oct 10, 2015 at 17:48
  • That's true, a local variable might end up being just a register (no stack use necessary). But assuming that it does go on the stack, is it right to call that "static allocation"? Commented Oct 10, 2015 at 17:49
  • Static variables exist for the life of the program. The stack (as above, nothing to do with C) is designed for temporary variables only. Commented Oct 10, 2015 at 17:53

2 Answers 2

4

The stack itself is statically allocated. Variables allocated in the stack come and go, as control flow enters and leaves their scope.

Sign up to request clarification or add additional context in comments.

17 Comments

@starriet: I'm not sure where your confusion here comes from. If I allocated a fixed-size string buffer, and start reading into it from a file, I could eventually overflow that buffer. At runtime. The buffer was allocated at compile time and overrun at runtime. Is that surprising? A stack is no different. You can't tell at compile time how many times a recursive function will be called (or how deep the call stack is, regardless of recursion), and so you can't tell how much stack space will be used by the program until it actually runs.
@starriet: You can't tell how much space the buffer might need, but nothing stops you from from declaring it static. The point is that static storage occupies a reserved range of addresses, but nothing forces the program to use all of it. It's just there, waiting to be used if needed. And so with the stack. Because, and this is crucial: the stack cannot be moved. So it is where it is (virtually speaking). That's static. If you dynamically reallocated the input buffer every time you read a block, it wouldn't overflow, but it might move. That's dynamic.
What happens with the stack at runtime, at least on some operating systems, is that not all stack's address range is actually mapped to real memory until an attempt is made to reference it. But don't let that confuse you. The addresses are still reserved to the stack.Optimistic mapping of virtual storage is a trick used to compensate for the fact that the stack cannot be moved. It's a cool trick. But it's not dynamic allocation, in the strict sense of the word. (And it applies equally to any uninitialised block of static storage.)
Oh, yeah. One other thing. Thread stacks are generally actually dynamically allocated, because they only live as long as the thread does. Once the thread ends, its stack is dead and the memory can be returned to the memory manager. Start a new thread, and you might or might not get the same memory addresses, because it's dynamic. The same with thread_local storage for that thread. But the main program's stack is not like that. It lasts from when you load the program until when the program terminates. Just the same as the (rest of) the program's static data.
But where the thread stack is the same as the main stack is that it cannot be reallocated because it cannot be moved. So even though it's a dynamic allocation, it has a fixed size and if you exceed it, you're toast. When you write threaded code, you have to be aware of that.
|
2

Stack is allocated in unit of stack frame.

  • When a function is called, a stack frame is allocated for it,
  • When a function returns, its stack frame disappear,

And, stack helps to store function arguments & local variables.

After a function get its stack frame, yes, within the stack frame the function use bytes of it as need dynamic.


Dynamic allocate stack like heap

If u want to allocate memory on stack like the way as heap, then you can use alloca() from <alloca.h>, it's quicker than heap, but in most case u don't need that, it has disadvantages, thus not suggested in general case.


Describe stack allocation in different context might make it more clear:

  • From the view of a linux thread, (by the way, each process has 1 thread on creation by default, as main thread), the stack is of fix size & allocated on thread creation, (2Mb for IA-32, 32Mb for IA-64, by default), and you can change the default size as need. So you can say this is fix, and static.
  • From the view of a function within thread or process, the stack frame is allocated for it from the thread's stack memory when the function starts, and the stack frame disappear when the function finish.
  • From the view of a non-static local variable inside a function, the variable is allocated from the stack frame of the function as need, dynamically.

So, should it be called static or dynamical, you decide.

3 Comments

Right, but is that still called "static"?
@LorenLugosch If a local variable is declared as static within a function, then it is not stored in the stack frame, instead it is stored in the initialized data segment or ininitialized data segment, so that the value won't lose between function calls. In this case, yes the variable is static, but it is not on the stack frame. This is about the c static keyword.
That is true, but the question is not about the nature of local variables declared as "static" (which I know to be statically allocated), but rather the nature of local variables which go on the stack. The question is: is it right to call stack memory "statically allocated"?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.