Back to the basic : Pointer to Array, Array of Pointers…

To the beginner of C/C++, one of the most confusing concept is the pointer. Although the concept of the pointer is quite understandable, the notation for pointers and arrays seems to confuse people. When I was a freshman, other students kept mumbling, “Pointer to Pointer”, “Pointer to Array”, “Array of Pointer”, “Array Pointer” or “Pointer of Array”. Because it is in English, it made me quite confusing also. Pointer to Pointer is the easiest to understand. But others were very confusing. It is because Korean is different from English. If I set up concept with terms, “Pointer to Array” and “Array of Pointers”, some of my friends* approached to me and asked what “Array Pointer” is or what “Pointer of Array” is. Semantically, “Array Pointer” means a pointer which is made for array, and “Pointer of Array” means “Pointer to Array”. So, the threes, “Array Pointer”, “Pointer to Array” and “Pointer of Array”, were the most confusing. In Korean, “to…” can mean same to “of…”.

When I came to the U.S., students from other countries didn’t seem to be confused by those. Probably some terms like “Pointer of Array” sound awkwardly. I don’t know if it is also true to native English speakers.

When I got interviewed from U.S. companies, I was quite impressed that they asked about every detail of C/C++. The questions was quite creative. And it gave me impression that they know how to manage project and programmers. The way they interview is totally different from the way you do in Korea. ( Nowadays, Google imported their interview style to Korea, and I have heard that Haan soft interviews like americans. ) And they asked me how to make 2D array dynamically. I answered my best solution. ( I did lots of experiment with dynamic array when I made a 3D graphics engine before, and found a way which was very flexible and very powerful. This code will be introduced later. ) However, they said that my answer was wrong. And they showed me how to make a “Pointer to Array” and using it, they built 2D arrays. So, I figured out that their intervew question was not creative. I found one book which contained questions they asked me. Hmm.. It turned out that it was not creative questions.
So, I told them why using pointer to array was not flexible, and why my approach was better. They nodded affirmatively. However, if I didn’t answer things, which I actually know, but forgot because I was out of those problems for a while, they thought me that I didn’t know, although I just needed to remind me of those.. I’m quite experienced programmer, but my English capability limited any quick answer or chatting. So, it gave good impression that I was not compelling.

Anyway, let’s go back to the root. It’s time to refresh things again!
In this post, I will show how to make “Pointer to Array”, and “Array of Pointers”, and also will show shortcomings of array notation and pointer notation to handle multi-dimensional arrays.

Let’s start with array notation and pointer notation.

void outputUsingArray( int array[][4], int n_rows, int n_cols )
{
	int i, j;

	printf("Output Using array\n");
	for( i = 0; i < n_rows; i++ )
	{
		for( j = 0; j < n_cols; j++ )
		{
			// Either can be used.
			//printf("%2d ", array[i][j] );
			printf("%2d ", *( *(array + i) + j ) );
		}
		printf("\n");
	}
	printf("\n");
}

void outputUsingPointer( int (*array)[4], int n_rows, int n_cols )
{
	int i, j;

	printf("Output Using Pointer to Array i.e. int (*array)[4]\n");
	for( i = 0; i < n_rows; i++ )
	{
		for( j = 0; j < n_cols; j++ )
		{
			printf("%2d ", *(*(array+i) + j ) );
		}
		printf("\n");
	}
	printf("\n");
}

How it is used is :

int _tmain(int argc, _TCHAR* argv[])
{
	int array[4][4] = { { 0, 1, 2, 3 },
						{ 4, 5, 6, 7 },
						{ 8, 9, 10, 11 },
						{ 12, 13, 14, 15 } };

	outputUsingPointer( (int (*)[4])array, 4, 4 );

	outputUsingArray( array, 4, 4 );

What is a problem with array notation is that dimension of array is static and functions like outputUsingArray() can be used only for the specific dimension.
However, accessing array using array notation is convenient.
Pointer to array notation can be used like outputUsingPointer(); However, this also has the same problem of the outputUsingArray() case.

If the pointer to pointer is passed, and if the function is designed so, to access row, n_cols*i, term should be used.
It is flexible, because one function can access any dimension of arrays.
However, you can’t use array notation.

By the way, before presenting the most flexible solution to it, let’s think about making a dynamic array using array of pointers.

	printf("Using array of pointers -- Half Dynamic\n");
	printf("------------------------\n");
	int *array3[4];
	int i;

	for( i = 0; i < 4; i++ )
		*(array3+i) = (int *)malloc( 4*sizeof( int ) );

	array3[0][0] = 0; array3[0][1] = 2; array3[0][2] = 3; array3[0][3] = 4;
	array3[1][0] = 0, array3[1][1] = 2, array3[1][2] = 3, array3[1][3] = 4;
	array3[2][0] = 0, array3[2][1] = 2, array3[2][2] = 3, array3[2][3] = 4;
	array3[3][0] = 0, array3[3][1] = 2, array3[3][2] = 3, array3[3][3] = 4;

	outputUsingPointer3( array3, 4, 4 );
	outputUsingArray3( array3, 4, 4 );

Then, the outputUsingPointer3() and outputUsingArray3() are :

void outputUsingPointer3( int **array, int n_rows, int n_cols )
{
	int i, j;

	printf("Output Using Pointer to Pointer i.e.\n");
	for( i = 0; i < n_rows; i++ )
	{
		for( j = 0; j < n_cols; j++ )
		{
			printf("%2d ", *(*(array+i) + j ) );
		}
		printf("\n");
	}
	printf("\n");
}
void outputUsingArray3( int **array, int n_rows, int n_cols )
{
	int i, j;

	printf("Output Using Array i.e. int array[][]\n");
	for( i = 0; i < n_rows; i++ )
	{
		for( j = 0; j < n_cols; j++ )
		{
			printf("%2d ", array[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

As you can see, the array can be passed as a pointer to pointer, and you can access it using array notation and pointer notation easily. It is quite flexbile.
However, the number of colums are static when such an array is declared. So, I called it “Half-flexible”.

By the way, can’t you pass the static array declared as int array[4][4] to the outputUsingPointer3() by casting it to (int (*)[4])? No. It is not possible. The Visual C++ 2005 compiler doesn’t allow it.
Also it would be handy if the array can be passed as a pointer to pointer but casted to (int (*)[n_cols] ) inside of the function. Then, the function can be used for any dimension of arrays. However, it is not possible also. Even with a cast statement, the compiler doesn’t allow putting a variable as its dimension. Probably, GCC allows it. Because GCC has its own extension which allows variables for setting dimension of arrays. But it is only for the GCC.

casting doesn\'t work

Now, it’s time to introduce the most flexible dynamic array.

	printf("Using Pointer to Pointer -- Fully Dynamic\n");
	printf("------------------------\n");
	int **array2;

	array2 = (int **)malloc( 4* sizeof( int * ) );

	// each row is a 1D array
	for( i = 0; i < 4; i++ )
		*(array2+i) = (int *)malloc( 4*sizeof( int ) );

	array2[0][0] = 0; array2[0][1] = 2; array2[0][2] = 3; array2[0][3] = 4;
	array2[1][0] = 0, array2[1][1] = 2, array2[1][2] = 3, array2[1][3] = 4;
	array2[2][0] = 0, array2[2][1] = 2, array2[2][2] = 3, array2[2][3] = 4;
	array2[3][0] = 0, array2[3][1] = 2, array2[3][2] = 3, array2[3][3] = 4;

	outputUsingPointer3( array2, 4, 4 );
	outputUsingArray3( array2, 4, 4 );

By using pointer to pointer, instead of pointer to array, to declare multidimensional array, you can achieve the convenience of array notation and the power of pointer notation as well as flexibility. Here, the outputUsingPointer3() and outputUsingArray3() are same as the example above. In short, you can use any notation in any case for your convenience.

Using pointer to pointer is semantically easy to understand and the most powerful.
This is the way I explained in one of previous interview. In most of books, only using pointer to array is explained, and I found out that many people had difficulty in understanding “Pointer to Array” and “Array of Pointer.”

If you have difficulty in memorizing what notation is for pointer to array and array of pointer, try this :

int (*array)[4] : (, ) operators (parenthesis, 소괄호, 小适弧) have higher priority because it is on the left of the [,] (brackets, 대괄호,大适弧). So, it is a POINTER to [4].
Again.. It is a POINTER. So, it means it is a pointer to array.

int *array[4] : [,] have higher priority than *, so, it is ARRAY of pointers.
It is not pointer, it is ARRAY.

About these ads

37 responses to this post.

  1. Posted by Fatboysam on July 27, 2011 at 10:44 AM

    Just a simple question, We all know that this declaration is

    int (*array)[4] : array is a pointer to an array of 4 integers.

    Now how do you make a typedef out of it. so that if you need a pointer to the type above, then you don’t have to type everything again, I hope I am clear in explaining my problem

    Reply

  2. Posted by Anthony on February 14, 2012 at 2:14 PM

    When you free the dynamic array do you just do free(array2); or do you have to free each row?

    Reply

    • Posted by jongampark on February 14, 2012 at 8:23 PM

      I removed each element and deleted the main thing, because C++ doesn’t know all about the allocated memory.

      Reply

  3. This is really interesting, You are a very skilled blogger.

    I’ve joined your feed and look forward to seeking more of your wonderful post. Also, I’ve shared your site in my
    social networks!

    Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 48 other followers

%d bloggers like this: