Accessing elements in a dynamic array in C

Problem description:

  • Previously, we have learned how to create a dynamic array

    Example: creating a dynamic array with 10 array elements

         int *A;
      
         A = malloc( 10*sizeof(int) );      
      

  • We still need to learn how to access the elements in this dynamic array...

  • Spoiler:

      • The C language has a beautiful mechanism to compute the address of an array element

      • This mechanism is called pointer arithmetic

Pointer arithmetic: defining the meaning of reference + integer operation
 

  • Recall these operators on the reference data type:

       &: returns the address of a variable  
       *: returns the variable at a given address   
      

  • There are other operators defined on the reference data type:

         + :  pointer addition
         - :  pointer subtraction        
      

    Note that C can define the meaning of the pointer addition and the pointer subtraction operation anyway it likes (but the operation must be useful)

Pointer arithmetic: defining the meaning of reference + integer

  • The expression:

         referenceVar + i // (i is an integer)                 
      

    evaluates (= returns) a reference typed value equal to:

         referenceVar + i*sizeof( *referenceVar )   
      

  • Usage:

        If the reference variable p  contains the base address 
        of a dynamic array, then:
      
           p + i = the address of the ith element of the array
      

Pointer arithmetic: defining the meaning of reference + integer
 

Example program illustrating the add operation of a reference typed value and a integer:

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

 int main( int argc, char *argv[] )
 { 
     int *A;     // sizeof( *A ) = sizeof(int) = 4
     int i = 3;

     A = malloc( 10*sizeof(int) );

     printf("A   = %p\n", A);
     printf("A+1 = %p\n", A+1); 
     printf("A+2 = %p\n", A+2);
     printf("A+i = %p\n", A+i);
 } 

Output: 0x557946b49260, 0x557946b49264, 0x557946b49268 and 0x557946b4926c

Pointer aritmetic illustrated
 

This diagram shows that A+i is the address of the array element A[i] (for an int typed array) assuming that A contains the value 8000:

The value in A is irrelevant as long as it is equal to the base address of the (dynamic) array

Pointer arithmetic: defining the meaning of reference + integer
 

When we use a short * pointer, the increase is by 2 bytes:

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

 int main( int argc, char *argv[] )
 { 
     short *A;  // sizeof( *A ) = sizeof(short) = 2
     int i = 3;

     A = malloc( 10*sizeof(int) );

     printf("A   = %p\n", A);
     printf("A+1 = %p\n", A+1); 
     printf("A+2 = %p\n", A+2);
     printf("A+i = %p\n", A+i);
 } 

Output: 0x564f71902260, 0x564f71902262, 0x564f71902264 and 0x564f71902268

Pointer aritmetic illustrated
 

This diagram shows that A+i is the address of the array element A[i] (for an short typed array) assuming that A contains the value 8000:

The value in A is irrelevant as long as it is equal to the base address of the (dynamic) array

Pointer arithmetic: defining the meaning of reference + integer
 

When we use a double * pointer, the increase is by 8 bytes:

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

 int main( int argc, char *argv[] )
 { 
     double *A; // sizeof( *A ) = sizeof(double) = 8
     int i = 3;

     A = malloc( 10*sizeof(int) );

     printf("A   = %p\n", A);
     printf("A+1 = %p\n", A+1); 
     printf("A+2 = %p\n", A+2);
     printf("A+i = %p\n", A+i);
 } 

Output: 0x557946b49260, 0x557946b49268, 0x557946b49270 and 0x557946b49278

Pointer aritmetic illustrated
 

This diagram shows that A+i is the address of the array element A[i] (for an double typed array) assuming that A contains the value 8000:

The value in A is irrelevant as long as it is equal to the base address of the (dynamic) array

Accessing a dynamic array
 

We can use the + operation on pointer variables to access elements in a dynamic array of any datatype as follows:

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

 int main( int argc, char *argv[] )
 { 
     int *A; 
     int i;

     A = malloc( 10*sizeof(int) ); // Create a dynamic array 

     for ( i = 0; i < 10; i++ )
        *(A + i) = i*i;   // Assigns i^2 to A[i] 

     for ( i = 0; i < 10; i++ )
        printf("%d\n", *(A + i) );
 }
   

Pointer arithmetic: defining the meaning of referenceinteger

  • The expression:

         referenceVar - intTypeValue       
      

    evaluates (= returns) a reference typed value equal to:

         referenceVar - intTypeValue*sizeof( *referenceVar )   
      

  • Note:

      • It is less common to use   referenceVar - integer in a C program because negative offsets are not used to access array elements