Lab #3, Friday 9/14

The purpose of this lab is to have you explore how memory is allocated for function calls and variables on the stack.

You must perform this lab in Linux on uaa-transformer.duckdns.org. You may get different results on a different machine.

Functions and the Stack

If you use the & symbol in front of a variable then C++ will give you the address in memory where the variable is stored. For example:

   int x;
   cout << &x << endl;
If this outputs 0x7fffaf6530ec then it means that variable x is stored in memory at address 0x7fffaf6530ec, which is a number in hexadecimal. If you want to output the memory address in decimal instead, typecast to a long:
   int x;
   cout << (long) &x << endl;
This output 140736701098204 on my execution (it will probably be different each time you run the program).

Here is another example that outputs the address of a variable in main and also the address of an int variable and an array variable in function foo:
  void foo()
  {
   char junk[1000];
   int num;

   cout << "num in foo is at address " << (long) &num << endl;
   cout << "junk[] in foo starts at address " << (long) &junk[0] << endl;
  }

  int main()
  {
   int i;
   cout << "i in main is at address " << (long) &i << endl;

   foo();
  }
Sample output is:
  i in main is at address 140734462996380
  num in foo is at address 140734462995324
  junk[] in foo starts at address 140734462995328

To Do - Part 1

  1. Each time a function is called a new stack frame is pushed onto the stack that contains all the local variables. Which direction in memory (smaller or larger memory addresses) does the stack grow?
  2. Devise an experiment to estimate how much memory is allocated to the stack. Probably the easiest way to do this is to write a recursive function that never terminates and runs until there is a stack overflow. If you add some diagnostics you can estimate how large the stack is. Your program doesn't need to output the stack size, but you should be able to manually calculate the size based on the output of your program. What is the approximate stack size?

Buffer Overflows

Here is some code that you can put into main that creates two arrays, outputs some of the addresses where elements are stored, initializes the char array to all dots, and then prints it out.

 int i;
 char a[10];
 int nums[5];

 cout << "a[0] is at address " << (long) &a[0] << endl;
 cout << "a[1] is at address " << (long) &a[1] << endl;
 cout << "nums[0] is at address " << (long) &nums[0] << endl;
 cout << "nums[1] is at address " << (long) &nums[1] << endl;

 // Initialize char array to all dots
 for (i = 0; i < 10; i++)
        a[i]='.';

 // YOUR CODE WILL GO HERE

 // Output contents of char array
 for (i = 0; i < 10; i++)
        cout << a[i];
 cout << endl;
Here is a sample output:
a[0] is at address 140734270786480
a[1] is at address 140734270786481
nums[0] is at address 140734270786448
nums[1] is at address 140734270786452
..........

To Do - Part 2

  1. Write code that changes ONLY the nums array where the comment "YOUR CODE GOES HERE" is located such that the letter 'A' is output among the dots. In other words, a change to the nums array would affect the values in the a array! Show your code, execution, and explain how this is possible to the TA. You may want to refer to the ASCII Code.