// dynamic memory allocation
/*
// advantages:
1. You can specify the size at RUNTIME
2. You can get more memory than on the stack
3. It sticks around (it does not disappear automatically -- i.e. it does not have "automatic storage duration")

You can use up the memory on the heap if you keep allocating
large arrays.
You should delete all dynamically allocated memory when you are done using it.
You do not have to delete in the same function that you allocated.
*/


#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{

  const int SIZE=1000;
  int num;

  int arr[SIZE];  // known at compile time

  // new operator  returns a pointer
  int *iptr;

/**********
never would ask for a single variable dynamically allocated, but this is for the sake of example 
**********/
  iptr = new int;

  *iptr=10;// assigns 10 to location on heap of this new int
  cout << "our number on the heap is " << *iptr << endl;
  
  delete iptr; // delete or free up a single variable


/**********
usually use dynamic memory for an array
**********/

  int largearray[1000000];

  cout << "enter a number of elements: ";
  cin >> num;
  iptr =  new int[num]; // give me an array of num elements of type int
  cout << "You've allocated an array of size " << num << endl;

 for (int x=0;x<num;x++)
     iptr[x]=0;

 //    *iptr++=0; WRONG you should never change the address to the beginning of the array since you'll lose access to the array.

     delete[] iptr;

try {
  for (int i=1;i<=1000000;i++)
    { 
     if (i%1000==0) cout << "i= " << i << endl;
     iptr =  new int[num];
// ......
     delete[] iptr;
    }
    }// end try
// newer compilers throw and exception called bad_alloc
  catch(bad_alloc)
    {  cout << "the memory was NOT allocated!!!" << endl;
       exit(1);
    }

// older compilers return NULL
  if (iptr==NULL)  {
      cout << "memory was not able to be allocated" << endl; 
      exit(1);
    }



// put a 6 into the 5th location of this dynamic array
  *(iptr+5)=6;
//OR
   iptr[5]=6;


/***************
// When you are done with the array, you ask the heap to 
// free it up by using the delete operator
//delete [] iptr;

********/
 
  return 0;
}
