1

I am bit confused with respect to pointer to arrays and just normal pointer and how to access. I have tried this...

int *ptr1, i;
int (*ptr2)[3];
int myArray[3] = {1, 1, 1};
int myArray1[5] = {1, 1, 1, 1, 1};
ptr1 = myArray;
ptr2 = myArray1;// compiles fine even though myArray1 contains 5 elements 
                 // and ptr2 is pointing to array of 3 elements.

printf("%d",ptr2[3]); // prints some garbage.

Why this statement is printing garbage? What is the correct statement? Can anyone explain?

OnlyQuestions
  • 169
  • 1
  • 8

3 Answers3

4

We can also declare pointer to array as

int (*ptr)[]; // ptr is a pointer to array.

When you do

ptr2 = myArray1;

compiler will throw you a warning message. Look boss types are not compatible. In some context Arrays decays into pointers. Warning message is because, when arrays decays into pointers, the decayed type is pointer. In this case, when you do

ptr1 = myArray; 

myArray decays into int *.

But when you do,

ptr2 = myArray1;

myArray1 decays into pointer that is int *, but the type of ptr2 is int (*)[].

In order to avoid warning, you should say

ptr2 = &myArray1; //&myArray1 returns address of array and type is int(*)[].

Why this statement is printing garbage? What is the correct statement? Can anyone explain?

printf("%d",ptr2[3]);// prints some garbage. 

Yes, But why? Lets see the correct statement first...(note that index should be less than 3)

printf("myArray1[%d] = %d\n", i, (*ptr2)[2]); 

We have to use (*ptr2)[i] to print the array element. This is because, just by mentioning ptr2, we will get the address of the array (not the address of some int). and by de-referencing it (*ptr2) we will get the address of 0th element of the array.

1

Pointer ptr2 is pointer to int array of size three

ptr2 = myArray1;  // you may getting warning for this 

should be:

ptr2 = &myArray1; // use & operator 

And

printf("%d", ptr2[3]);

should be:

printf("%d", (*ptr2)[2]); // index can't be 3 for three size array 
 //          ^^^^^^^  

Notice parenthesis around *ptr2 is needed as precedence of [] operator is higher then * dereference operator (whereas if you use pointer to int you don't need parentheses as in above code).

Read Inconsistency in using pointer to an array and address of an array directly I have explained both array to access array elements. (1) Using pointer to int (2) pointer to array

Whereas ptr1 = myArray; is just find, you can simply access array elements using ptr1[i] (not i values should be 0 to 4)

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
1
int (*ptr2)[3];

This signifies that (*ptr2) is the identifier which contains the location in memory of the beginning of an integer array. Or, rephrasing, that ptr2 is an address. That address contains a value. That value is itself the address of the beginning of an array of ints.

So when you write ptr2 = myArray1 you are basically saying "The address of my address holder is the address of the beginning of myArray1".

So when you go to print the value using ptr2[3] you are actually printing the value of the memory address of myArray1, incremented 3*sizeof(ptr2) units. Which is why it looks like garbage, it's some memory address.

What should be in the print statement is (*ptr2)[3] which means "Take the address of ptr2 and get the value stored at that address. Next, using that second address, increment it 3*sizeof(int) and get the value stored at that incremented address."

Arrays in C are nothing more than a contiguous region of allocated memory. Which is why saying:

int *x = malloc(3*sizeof(int));

Is the same as:

int x[3];

Since [] and * both dereference a pointer, if we wanted to access the second element of either array, we could write:

int value = x[1];

or

int value = *x+sizeof(int); // Since *x would be index 0

Two of the major differences are that the [] notation is a bit easier to read but lengths must be determined at compile time. Whereas, with the *x/malloc() notation, we can dynamically create an array or arbitrary length.

  • "int *x = malloc(3*sizeof(int)); Is the same as: int x[3];" No it isn't. One is a pointer. One is an array. They are very different. – newacct Oct 25 '13 at 22:29