/* This program demonstrates: * 1. Arrays and Pointers - pointer arithmetic * 2. Dynamic Memory Allocation * 3. Dynamic Arrays * * Pointer Arithmetic * Since pointers are numbers (integers) we can do math with them. * However, the second operand in the operation is always multiplied by the size * of the type of the variable before the math is done. * We can make use of this property to work with arrays * * Pointers and arrays * When we declare an array, we are actually declaring a contiguous space of the * required amount of memory, and then uses the name os the array as a pointer to * the starting address of the array * Every time we use the [] operator with the array, we are actually doing pointer * arithmetic and then dereferencing the pointer * So, we can actually do the pointer math and dereference the pointer to move * through the array. * We can also actually change and update the pointer to move through the array. * However, if we do this, we have to make a note of the fact that the array name * is no longer pointing at the starting address of the array * * Dynamic Memory allocation is when we * a. Allocate Memory outside the function call stack in heap memory * b. We do this during runtime (after the program has started running) * * The allocated memory must be explicitly destroyed by the programmer * * To allocate: Use the "new" operator/ keyword * * To deallocate: Use the "delete" operator/keyword * * Dynamic Arrays: * So far, we have been declaring arrays in stack space. These arrays need to have * their size decided BEFORE COMPILING. That is why we had to use integer literals * or constant integers for size while declaring the arrays. We decided this size * hoping that it would be "large enough" to hold all the data the user is going * to put in. * * Also, we cannot create arrays in one function (that is not main) and use it in * other functions. * * Dynamic memory solves both of these problems. * 1. Declaration * We declare dynamic memory using the keyword "new". * When we declare a variable/array dynamically, the variable/array is created in * a completely different area of memory called the heap. This happens at RUNTIME. * So, we can use a variable to specify the size of the array. * 2. Access * We can access variables/arrays created in heap memory ONLY through a pointer. * 3. Deleting * Since we create this memory in runtime, this is not automatically deleted when * we return from a function. This is useful because we can create arrays in a * function and return it. However, we should take care to delete the memory we * created before we exit the program. To delete memory we created, we use the * keyword "delete". Please note that deleting doesn't have to be done in the * same function that created the array. * */ /* When we want to return an array from a function, the return type has to be * a pointer of the type of the array that we're returning. */ int* readArray(int count); int* readDynArray(int count); int main() { int *ptr; // declare a pointer //Arrays can be easily manipulated by pointers. int array[10] = {12, 8, 9, 10, 15, 23, 45, -100, 6, 41}; /* The following line will store the starting address (address of * location 0) in the pointer arrPtr */ int *arrPtr = array; // array names work like pointers // Both of the following lines will print the starting address of the array cout<<"arrPtr: "< ptr op (type_size * x) * * The following loop runs 10 times, each time it dereference the pointer * after adding i to the pointer * Since it uses pointer arithmetic, the actual value added to the pointer * is i * sizeof(int) = i*4 here */ cout<<"\nPrinting array, with pointer arithmetic:\n"; for(int i=0; i<10; i++) cout<< *(arrPtr +i) <<"\t"; /* The following loop does the same thing as the previous loop, but it makes use of operator precedence * to combine the addition and dereferencing into one step. * It also has the effect of changing the pointer. * At the end of the previous loop, the pointer will still be pointing at element number 0 of the array. * At the end of the following loop, the pointer will be pointing at the spaces beyond the last element * (element 9) of the array. */ cout<<"\nPrinting array by changing the pointer:\n"; for(int i=0; i<10; i++) { cout< arrPtr = arrPtr + (4*1) } cout<<"After the loop: arrPtr: "<> * ptr; cout<<"Value of dynamic integer variable created: "<< * ptr <>size; intArr = readArray(size); // The previous line will retrun an invalid reference, which would crash if we used it /* Instead of using the readArray function that creates an in-stack array * and returns an array that is subsequently destroyed, we can create a dynamic * array in the function, retrun it, use it in main, and delete it when it * is no longer required. */ intArr = readDynArray(size); cout<<"\nPrinting from main: \n"; for(int i=0; i>array[i]; cout<<"Printing from the function:\n"; for(int i=0; i>array[i]; cout<<"Printing from the function:\n"; for(int i=0; i