Lecture 17:  Dynamically Allocating Arrays

 

Objectives of this lecture

q       Learn the relationship between arrays and pointers

q       Learn another way of accessing elements of an array—using pointers

q       Learn how arrays may be allocated dynamically

 

Relationship between Arrays & Pointers

q       Arrays and pointers are very closely related in C

q       The name of an array is in fact a pointer constant – the address of the first element

q       Thus, it may be assigned to a pointer variable.

q       E.g.  If we have the declaration:

int x[5]={10,20,30,40,50}, *p;

q       Then it is possible to make the assignment:

p=x;

q       This is equivalent to :

p=&x[0];

q       With either of the above statements, the first element of the array can be accessed either as :

x[0]  or *p

q       Since x is an address, the first element can also be accessed as:

*x.

q       Similarly, C allows the pointer variable p to be subscripted.  Thus the first element can be accessed as:   

p[0]

q       The second element can be accessed using any of the following:

x[1],  p[1],  *(x+1) ,  or  *(p+1).

q       The last two expressions are example of pointer arithmetic, one of the powerful features of C.

q       What then is the difference between x and p?

q       The difference is that x is a constant while p is a variable.  Thus, x cannot be changed, but p can be changed. 

E.g.   p++;

q       This makes p to now points to the second element of the array.

q       The following program further shows how pointers may be used to manipulate elements of an array.

 

 

#include <stdio.h>

main()

{  int i, *p, x[5]={10,20,30,40,50};

   p=x;                /* p holds the address of x[0] */

   p++;                /* p holds the address of x[1] */

   printf("\n%d", *p); /* prints 20 */

 

   *p=25;              /* x[1]=25 */

   printf("\n%d", x[1]);/* prints 25 */

 

   x[2]=*(--p)+3;      /*p points to x[0] and x[2]=13 */

 

   for (i=0; i<5; i++)      /* prints all elements and */

     printf("\n%d",*(p+i)); /* keep p as it is – pointing to x[0]

  */

   for (i=0; i<5; i++)      /* prints all elements and */

     printf("\n%d", *p++);  /* change p along */

 

   for (p=x; p<&x[5]; p++)  /* prints all elements and */

     printf("\n%d", *p);    /* change p along */

 

   return 0;

}

 

Pointer Arithmetic and Element size:

q       It is important to note that in pointer arithmetic expressions such as p+1, it is not 1 that is actually added to p, but what ever number of bytes that are necessary to reach the next element – and the expression is machine independent.  Thus if p is int , on a PC, 2 bytes are added, while on UNIX, 4 bytes are added.

q       However, if p and q are are both pointing to elements of an array, then p-q yield the int value representing the number of elements between p and q.  The following code illustrates this:

 

#include <stdio.h>

main()

{  double x[2], *p, *q;

   p=x;

   q=p+1;

   printf("%d\n", q-p); /* 1 is printed */

   printf("%d\n", (int) q - (int) p);  /* 8 is printed */

   return 0;

}

Allocating Array at run-time

q       Since pointers can be used to access a sequence of memory cells, and since sequence of memory cells can be obtained at run-time using malloc, we can combine these two features to allocate array at run-time.

q       The following programs shows how this may be done.

 

#include <stdlib.h>

main()

{  int i, *p, size;

   printf("\nEnter size of your array: ");

   scanf("%d", &size);

 

   p=(int *)malloc(size * sizeof(int));

 

   printf("\nNow input %d integers: ", size);

 

   for (i=0; i<size; i++)

      scanf("%d", &p[i]);

 

   printf("\nThe values after multiplying each by 2 are: \n");

 

   for (i=0; i<size; i++)

      printf("%d\n", p[i]*2);

 

   free(p);

 

   return 0;

}

 

Note:

q       It is important to always use free to explicitly return the memory obtained by malloc.

q       Before using free(p) to return the memory obtained using malloc, make sure that p is pointing to the base element of the array (element 0).