Wednesday, Aug 16th

Last update12:59:40 PM GMT

Pointers:The Array Relation

Write e-mail

I will suggest before reading the below article you read the article on Pointer: Basics. But if you think you already are familiar with the basics, go on reading. :-)

argaiv1060

In this article, we will move a step further and discuss about array relation of pointers without which the discussion on pointers is always incomplete.

By definition, an array is a group of contagiously located data elements in memory.Consider the following:

int my_array[] = {1,2,3,4,5};

Here we have an array containing 5 integers. We refer to each of these integers by means of a subscript to my_array, i.e. using my_array[0] through my_array[4]. But, we could alternatively access them via a pointer as follows:

int *ptr;
ptr = &my_array[0]; /* This point our pointer at the first integer in our array */

Now we can print our array either using the array notation or by dereferencing our pointer:

for (i = 0; i < 5; i++)
{
 printf("my_array[%d] = %d   ",i,my_array[i]);   
 printf("ptr + %d = %d\n",i, *(ptr + i));        
}

That is both will yield the same result as my_array[i] and *(ptr + i) are equivalent.

You can try to see the results of printf using *ptr++ and *(++ptr) and try predicting the outcome.

This can be inferred from what I explained in the last article that (ptr + i) will basically refer to an address which is ‘i’ integers ( i * 4 bytes) away from the first element (the one to which ptr is currently pointing to).

The C standard states that wherever we use &var_name[0] we can replace that with var_name, thus in our code where we wrote:

ptr = &my_array[0];

we can write: ptr = my_array; to achieve the same result.

This should not make you think that name of an array is also a pointer to its first element. Though it sounds to be a valid proposition, it is not. See, we can write ptr = my_array but my_array = ptr is not valid. This is because ptr is a pointer variable but my_array is a constant.

So its more logical to think of array name as the address of the first element of the array (something which is fixed and cannot be changed).

But actually the array name is a constant pointer. Constant pointer is a pointer which cannot be made to point to a different memory location after being defined once and hence can never be an l-value in assignment statement. So the array name is actually a constant pointer pointing to the first address of the 1D array.

Now moving further to a 2-D array. When we declare a 2D array of integers like my_array[3][4], as a programmer we mean a table in memory which has 3 rows and 4 columns = 12 integers and we can reference a particular element in second row and third column as my_array[1][2]. This was easy.

But how are arrays stored in memory? A 2D array is also stored in contagious memory locations like a 1D array. It is stored one row after the other (row-major form).So the exact memory address where we find an element belonging to ith row and jth column is (&(my_array[0][0]) + i*n + j) where n will be the no. of columns, in our case = 4. Also remember: as explained earlier when we are incrementing the address we are not incrementing in bytes but by the actual size the datatype occupied like 4 bytes in our case for an int.

Now we try relating this with pointers like we did for a 1D array. Remember this as a mantra: a 2D array is actually a 1D array whose each element is also a 1D array. That is, a 2D array with n rows and m columns is a 1D array having n elements and each of the n elements is itself a 1D array of m elements. :-). See again the diagram how the memory is laid out for a 2D array:

pointers

So if you visualize the 2D array in the above way, you will be able to conclude that array name here again the address to the first element of the 1D array (which again is an array).That is, my_array is same as &my_array[0][0]. For a regular 1D array it was a normal datatype like an integer, char etc.

Lets take a pointer pointing to this 2D array. Can we take it a:

int* ptr =&my_array ? Yes we can. The pointer ptr will be pointing to the memory address storing the element my_array[0][0]. So to access the element at my_array[i][j] we can move out ptr forward by i* (no. of columns + j) and access the corresponding element by dereferencing it as:

int x = *(my_array + 4*i +j); //Test the formula yourself by taking examples

Accessing the array element through pointer in this way is convenient only if we have a statically allocated memory like the static array we have above, because we know in advance how many rows and columns we have for this 2D array. But for dynamically allocated memory where we at run time allocate the memory as to how may rows and how many columns we have for a particular 2D array, this approach doesn’t look a good way to access the array elements using the above formula as in case of dynamic 2D array we can have different no. of elements in each row so framing a fixed formula is not possible. Nonetheless, obviously we can come out with a solution of using the above method also but it wont be a good looking one.

We will study about the dynamic arrays in the next article when we discuss the double pointer (a pointer to pointer). Double pointer is the approach is what we normally follow for a dynamic 2D array.

If you are clear about the concepts discussed so far, then its right time to move to the more complicated stuff on Pointers. Read on.

Happy Pointers ;-)

Share this post



Add comment

Please refrain from using slang or abusive language in the comments.
To avoid waiting for your comment to be published after being reviewed, please log in as a registered user.


Security code
Refresh

Web Hosting