You are on page 1of 3

Pointers and dynamic memory

Dynamic memory allows you to build problems with data that is not of fixed size at compile time. Stack and Heap Memory in your C++ application is divided into two parts the stack and heap. One way to visualize the stack is as a deck of cards. The current top card represents the current scope of the program, usually the method that is currently being executed. For example suppose we have a program as shown below. int subtract(int x, int z){ return x z; } int add(int a){ int c = a + subtract(5,8); return c; } void main(){ int m[2] = {1}; m[1] = add(3); } When the program is compiling, compiler decide the stack frame size (i.e. memory size) for each method. That is before we start to run the program when we compile, needed memory size for each method is decided and fixed. When you call a method, the method lands on the top of the stack. Actually the stack frame is pushed onto the stack. It holds the state of the method including which line of code is executing and the values of local variables including parameters. The method at the top of the stack is always the currently running method. When the above code is running it will start from the main() method. The main() method goes on the stack. That means stack frame of the main() method is now on top of the stack. That is currently running method is main().
x z

subtract() add() a main()


m

add() a main()
m

add() main()

a m

main()

1 The main() method goes on the stack. That is stack frame of the main() is now on top of the stack. The variables define in main() also go on the stack.

2 Then main() is calling add(). So a new stack frame is placed (pushed) on top of the stack. So add() has its own stack frame or memory area to work with. Now currently running method is add(). Until add() finishes main() has to wait.

3 When add() is calling subtract(), new stack frame for subtract() is placed on top of the stack just like a new card is put on the deck.

4 subtract() completes and popped off the stack. So, x and z are out of scope and dead. When add() resumes where it left off, a and c are alive and back in scope. Variable m is alive but not in scope until add() completes.

A method stays on the stack until the method hits its closing curly brace which means the method is finished running. When the subtract() is finished running, it goes (or popped) off the stack. Execution goes back to add() method and picks up at the line following the call to subtract() (reurn c;). The local variables (including parameters) are alive as long as its stack frame is on the stack. In other words, until the method completes. When the subtract() is finished running and goes off the stack (i.e. released the memory), the local variables declared within the method (x and z) are also gone and no longer in the memory. A local variable is in the scope only within the method in which the variable was declared. When its own method calls another, the variable is alive, but not in scope until its method resumes. You can use a variable only when it is in scope. After add() calls subtract(), currently running method is subtract(). Local variables of add() (a and c) are alive but not in scope. Local variables of subtract() (x and y) are alive and in scope. To use a and c we have to wait until the subtract() finishes execution. Lets take below shown code to learn life and scope of a local variable. Variable hours is declared in sleep() method. void eat(){ hours = 6; //This wont compile. This will give undeclared identifier compile time error. } void sleep(){ int hours = 12; eat(); } Local variable hours can be used only within the sleep() method. In other words, scope of hours is only within its own method. No other methods can see hours. eat() cant see hours variable. Since hours is not in eat()s stack frame, eat() does not know anything about hours. Stack frames are nice because they provide an isolated memory workspace for each method. But due to the way that the stack works, the compiler must be able to determine size of the stack frame at compile time. Since the stack frame size decided and fixed at compile time, you cannot declare a variable whose size is going to be changed during the run time. Suppose you want to declare an array with variable size, you cannot declare an array as shown below. int arraySize = 3; int myVariableArray[arraySize];// This line wont compile. Since the number of elements of the array is not a constant but a variable, compiler cannot decide the size of the array. It is because compiler wont substitute the value of the variable arraySize at compile time. Value of the arraySize will be substitute at run time. Therefore compiler will fail to determine the exact size of the array hence size of the stack frame. However, it is possible to specify the size of an array at run time by using dynamic memory and placing the array in the heap instead of the stack. The heap is an area of memory that is completely independent of the current method or stack frame. You can put variables on the heap if you want them to exist even when the method in which they were declared has completed. The heap is less structured than the stack. You can think of it as just a pile of bits. Your program can add new bits to the pile at anytime or modify the bits that are already in the pile. To allocate an array dynamically, you first need to declare a pointer: int* myVariableArray; The * after the int type indicates that the variable you are declaring refers to some integer value. It does not yet point to anything specific because you havent assigned it to anything. It is still uninitialized variable.

To initialize the pointer to new heap memory, you use new command: myVariableArray = new int[arraySize]; This allocates heap memory for the array of arraySize (i.e. for three integers). The real use of pointers is that we can allocate memory dynamically. After this code is executed both stack and heap will look like this. Stack Heap

myVariableArray[0] myVariableArray[1] myVariableArray myVariableArray[2]

Here the pointer is still in the stack and pointing to the array which is in the heap. Here value of arraySize can be changed at run time before we create an array using new command. You can let user to decide the array size (number of elements) and then create an array of that size. cin>>arraySize; myVariableArray = new int[arraySize]; This will allocate heap memory dynamically at run time (when program is running) according to the number of elements of the array. Suppose you declare and initialize a pointer as shown below. int array[2]; int * ptr = array; Here both pointer ptr and array are in the stack. Pointer is pointing to a static array. In the static array number of elements is fixed at compile time and we cannot change the size of the array at run time. If we want to change the size of the array we have to create it using new command to allocate heap memory dynamically as described above.

You might also like