hi friends,
i was doing functions and i encountered this thing that automatic variables are stored as stacks and static,global as heaps.I am in a bit confusion about these terms......can someone help me out...plz

Hi,

Please search at search at google at there are lots of information regarding this.

But for very simple info, every process created by the operating system has 3 memory blocks to store variables,fucntions.

These are:
Heap: Dynamically allocated memory are created here. if you allocate any memory using alloc/calloc/malloc, new, operator new, these will go here.
Static memory: where global and static variables are stored.
Stack: Stack is where auto vairables are stored, automatic variables are the variables which you have declared in the function. like, int a; float b; int a[100]

I hope this helps.

@alwaysLearning0 : What you said is almost right but there is nothing called static memory in the context we are talking.

every process is arranged into following segments :
Text Segment : Which holds the code.
Data Segment : Which holds the static and global variables.
The remaining memory allocated to the process is shared by Stack and Heap which grow from opposite ends.

So as said earlier the global and static variables which can be accessed throughout the program is stored in +data segment. And all the variables that we declare in any function (including main) which are non static are given memory space int the respective functions stack which is formed when the function is called and destroyed when the function returns.

@csurfer,

A question in Stroupstrup's book, that I was not considering trying, is: Which way does the stack grow? Which way does the free store (heap) grow? Write a program to that answers those questions.

What you just said about stack and heap growing from opposite ends suggests that this issue might be pretty important. If one type of memory has increasing address values and another has decreasing address values, then the way pointers are used should depend on the type of memory. By that I mean, if we want to move a pointer along an array, or across several arrays, then we should use the increment operator (++) for one type of memory and the decrement operator (--)for the other type.

Does that make sense? Would a program to show this involve creating a series of variables, then printing each sequential variable and its address? That should show whether the next variable is put into a higher address or lower address than the previous variable.

I think this issue is best illustrated by a simple example. Consider the following simple program:

const int four_factorial = 24;

int some_function(int* c, int* d) {
  return c[0]*d[0] + c[1]*d[1] + four_factorial;
};

int main() {
  int* a = new int[2];
  int b[2];

  int result = some_function(a,b);
  delete[] a;
  return result;
};

Ignoring a few things like housekeeping values, optimization, calling conventions or any superfluous temporaries, we can easily draw the memory pattern of the program. First, we could imagine that the program's executable file would look like this:

//code segment:
some_function:
  //compiled code for some_function
main:
  //compiled code for main
//data segment:
[four_factorial] //a memory slot holding the constant value of four_factorial

Now, once loaded and stopped just before calling some_function(), the program in RAM would look like:

//code segment:
some_function:
  //compiled code for some_function
main:
  //compiled code for main
//static data segment:
[four_factorial] //a memory slot holding the constant value of four_factorial
//memory segment (heap + stack):
//start of heap section:
[a[0]]     //value of a[0]
[a[1]]     //value of a[1]
//end of heap section
//... a whole bunch of free space (not allocated to either heap or stack)
//start of stack section
[result]   //some space for result variable
[b[0]]     //value of b[0]
[b[1]]     //value of b[1]
[a]        //value of the pointer variable a
//end of stack section

Now, if you would stop the execution within some_function, the new memory segment:

//memory segment (heap + stack):
//start of heap section:
[a[0]]     //value of a[0]
[a[1]]     //value of a[1]
//end of heap section
//... a whole bunch of free space (not allocated to either heap or stack)
//start of stack section
[c]        //value of pointer variable c
[d]        //value of pointer variable d
[result]   //some space for result variable
[b[0]]     //value of b[0]
[b[1]]     //value of b[1]
[a]        //value of the pointer variable a
//end of stack section

After some_function has returned, the start of the stack is moved forward to just before the variable "result", like it was before. After the array "a" is deleted, the end of the heap would go back to the start (making it empty).

There is, as far as I understand, no particular reason why the heap is at first and grows in the increasing address space and vice versa for the stack, it could easily be the other way around. What would not be possible, however, is having both in the same section. By nature, the stack is deterministic at compile-time, i.e. every function allocates the same, continuous chunk of the stack at every call and that chunk becomes its ball-park where it can operate on its local variables. While the heap is, by nature, undetermined at compile-time, and thus, requires fancy algorithms to allocate and deallocate chunks that are generally growing but also tries to reuse deallocated space ("holes" in the heap section).

@Nathaniel10: >> By that I mean, if we want to move a pointer along an array, or across several arrays, then we should use the increment operator (++) for one type of memory and the decrement operator (--)for the other type.

Absolutely not. As you can see from my simple example, any array, like int[2], whether it is local and static, like "b" on the stack, or dynamically allocated, like "a" on the heap, is still addressed the same way starting from the pointer to "a[0]" or "b[0]". So, you don't treat them differently, and thank god you don't have to, it would be a real nightmare.

>>Does that make sense? Would a program to show this involve creating a series of variables, then printing each sequential variable and its address?

Sure, that's what you would do to see that heap allocated variables will have much lower address than stack variables (and that sometimes comes in handy in debugging memory-related problems, you can often recognize if a problematic variable is from the stack or from the heap just by looking at the address, i.e. big means stack, smaller means heap). To verify the point I just mentioned before, you could just use the test program above and print the addresses of "a[0]", "a[1]", "b[0]" and "b[1]", and see that "&a[0] << &b[0]", "&a[1] = &a[0] + sizeof(int)" and "&b[1] = &b[0] + sizeof(int)".

Comments
Excellent guide.
This article has been dead for over six months. Start a new discussion instead.