Computer Science 1622
Computer Science II

Laboratory Assignment 6
Playing with Pointers
Due at the end of Lab

Introduction

A pointer is a derived data type -- it is a data type built from one of the standard types. Its value is any of the addresses available in the computer for storing and accessing data. A pointer variable is a variable that contains the address of another variable where the address of a variable is the address of the first byte occupied by that variable.

Pointers, like variables, have to be assigned values. Otherwise they point to unknown locations and it might lead you to a run-time error. These errors can be difficult to debug until later in the program execution. An example of such a run-time error is shown in the following code.

One of the most useful applications of pointers is in functions. Every time we want a called function to have access to a variable in the calling function, we send the address of that variable to the called function and use the indirection operator to access it. In effect, if we need to send back more than one value from a function, we can use pointers.

The name of an array is a pointer to the first element. Hence, the address of the first element and the name of the first array both represent the same location in memory. If we have an array, 'a', then 'a' is an address pointing to the first element and (a+i) is an address pointing to the ith element. In other words, the two expressions *(a+n) and a[n] are identical.

Dynamic Memory allocation uses predefined functions to allocate and release memory for data while the program is running. The functions malloc, calloc and realloc are used for memory allocation. The function, free, is used to return memory when it is no longer needed. The function calloc is primarily used to allocate memory for arrays. An example of its use is shown in the following program.

This lab will help you understand certain manipulations that you can do using pointers and help you realize some of the common programming errors involved in their use.

The Program

The first thing that the following program does is to prompt the user to input the size of an integer array for which memory is going to be allocated dynamically using the calloc function. It then fills in the elements of this array with values in the numerical order starting from 0 till the (size of the array-1) and then prints this array. For example the 0th element will have 0 as its value, the first element will have 1 and so on.

The program then prompts the user to input the size of a new integer array to be generated. It then calls the function Minimum which in turn returns a pointer to the smallest element in this integer array.

Things To Do !

  1. When you run the program the first time, you will come across a few run-time errors. These errors are marked as /*ERROR 1*/ and /* ERROR 2*/ in the code.

    Eliminate the errors one at a time running the program after you eliminate each.

  2. Another job of yours will be to add code to create a new array dynamically whose size is equal to the smallest element of the array (Minimum_In_Array), that we had found previously. Then update the elements in this dynamic array to contain successive fibonacci numbers.

    For example, the first element of this array should contain first fibonacci number(0),the second element should contain second fibonacci number(1) and so on and the last element should contain the (n-1)th fibonacci number where n is the size of this array.

    For this you can use the function fib(i) provided in the following code which returns the ith fibonacci number.

  3. Once you have added this portion of the code, run the program several times for different sizes of arrays (both for the first two arrays as well as for the new dynamically allocated array).

The Code

#include <stdio.h>
#include <stdlib.h>

#define MAX 30

void Read_Array1(int* Dyn_Array,int* N){

   int i;
   int j;

   do{
      printf("What is the size of the array you want?(keep it within 20):");
      scanf("%d",N);
   }while ((*N <= 0) || (*N > MAX));
   Dyn_Array = (int *) calloc(*N, sizeof(int));
   for(i = 0;i < *N;i++)
      *(Dyn_Array + i) = i;
   
   free(Dyn_Array);
   Dyn_Array = NULL;
   /* ERROR 2*/
   /* In the following statements we have used the pointer Dyn_Array even 
      after releasing the memory associated with it.  Your program may
      continue to run, but the data may be destroyed if the memory area is
      allocated for another use.*/
   /* In order to avoid this, move the above 2 statements associated with 
      releasing the memory and clearing the pointer, after the code where
      you have printed the Dyn_Array*/
   printf("The values in this dynamically allocated array are:\n");
   for(j = 0;j < *N; j++)
      printf("%5d",*(Dyn_Array + j));
   printf("\n");
} 


void Generate_Array2(int *Pointer_to_Array,int *N) {

    int i;
    do {
      printf("What is the size of the array you want?(keep it within 20):");
      scanf("%d",N);
    } while ((*N <= 0) || (*N > MAX));

    printf("The generated array has the following elements:\n");
    for(i=0;i<(*N);i++) {
      *(Pointer_to_Array+i) = rand() % 50;
      printf("%d\n",*(Pointer_to_Array+i));
    }
}

int* Minimum(int *Pointer_to_Array, int N) {
    
    int *pWalk;
    int *pLast;
    int *pMin;

    pLast = Pointer_to_Array + N - 1;
    pMin = Pointer_to_Array;
    for(pWalk = (Pointer_to_Array + 1);pWalk<=pLast;pWalk++) {
      if(*(pWalk) < *(pMin))
	pMin = pWalk;
    }
    return pMin;
}

long fib(long i){

  if((i == 0)||(i == 1))
    return i;
  return(fib(i-1) + fib(i-2));
}


void main() {

  int Array1[MAX];
  int N;
  int Array2[MAX];
  int Size;
  int* Minimum_In_Array;
  int Min;

  Read_Array1(Array1,&N);
  
  Generate_Array2(Array2,&Size);
  
  Min = *Minimum_In_Array;
  printf("min is %d\n",Min);
  /* ERROR 1 */
  /* In the above 2 statements we have tried to use a pointer variable
     (Minimum_In_Array) before it has been assigned an address. These 2 
     lines can be removed from the code without affecting rest of the code */

  Minimum_In_Array = Minimum(Array2,Size);
  printf("\nThe minimum element in the array is : %d\n\n",*Minimum_In_Array);

 /* write code here to create a new array dynamically whose size is equal 
    to the minimum element of the previous array(Minimum_In_Array) that we just 
    found. Then update the elements in this dynamic array to contain successive
    fibonacci numbers.
For example, the first element of this array should contain first fibonacci number(0),the second element should contain the second fibonacci number(1) and so on and the last element should contain the (n-1)th fibonacci number where n is the size of this array.*/ }

What to turn in

Turn in a hard copy of your final program. Also, turn in atleast copies of 2 outputs for your program with the array sizes being different in them. Also make sure the size of the new dynamically allocated array is also different in each of them.