gomson
gomson

Reputation: 41

Pointer to array dilemma

I have a rather simple question about arrays and pointer to arrays. consider this code fragment..

int (*ptr)[3];               //A pointer to an array of 3 ints
int arr1[3] = {2,4,6,};      
ptr = &arr1;                //ptr now points to arr1

//3 different ways to express  the same address
cout << &arr1 << "\t" << arr1 << "\t" << &arr1[0] << endl;

Now if:

&arr1 == arr1 == &arr1[0]..

why is this code not correct:

ptr = arr1;

or

ptr = &arr1[0];

This has been driving me crazy...so please any explanation would be appreciated. Also please not that this is not an homework question, just something I'm trying to get a grips on.

Upvotes: 2

Views: 175

Answers (4)

Nagesh Nanjundachari
Nagesh Nanjundachari

Reputation: 29

Below programme will help you to better understand difference between pointer_to_first_member_of_array, pointer_to_1D_array, pointer_to_2D_array. Please carefully look at the programme, execute it and see output.

#include<stdio.h>

int priv_element = 88;

int array[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int next_element = 99;

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

  int *ptr_to_first_element = &array[0][0];

  int (*ptr_to_1d_arry)[5] = &array[0];

  int (*ptr_to_2d_arry)[2][5] = &array;

  printf ("Print first num of first array of 2-Dim array: %d\n",
      *ptr_to_first_element);

  ptr_to_first_element += 5;

  printf ("Print first num of second array of 2-Dim array: %d\n",
      *ptr_to_first_element);

  printf ("Print first num of first array of 2-Dim array: %d\n",
      (*ptr_to_1d_arry)[0]);

  ptr_to_1d_arry++;

  printf ("Print first num of second array of 2-Dim array: %d\n",
      (*ptr_to_1d_arry)[0]);

  printf ("Print first num of first array of 2-Dim array: %d\n",
      (*ptr_to_2d_arry)[0][0]);

  ptr_to_2d_arry++;

  printf
    ("Now you increased to point end of 2d-array space. So next to it is next_element on data-seg: %d\n",
     (*ptr_to_2d_arry)[0][0]);

}

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 222477

When you printed the various expressions, it showed you that their values were the same. However, they do not have the same types.

C and C++ include type features to reduce human mistakes and to make it easier to write complicated code. Suppose you had an address in some pointer p and C/C++ allowed you to do either:

float *f = p;

or:

int *i = p;

This would be a mistake, because, generally, whatever bits are in the memory at p do not represent both a useful int and a useful float. By enforcing rules about types, the language prevents a programmer from making a mistake here; the pointer p can only be assigned to another pointer of a compatible type, unless the programmer explicitly overrides the rules with a cast.

Similarly, your ptr is a pointer to an array of three int. At first, it might seem like your arr1 is also an array of three int, so you should be able to assign ptr = arr1;. This is wrong because ptr is merely a pointer, but arr1 is an entire array object. You cannot put an entire array into a pointer; you need to put a pointer to the array into the pointer. To get a pointer to the array, you use the & operator: ptr = &arr1;.

Another thing that is confusing here is that C/C++ includes an automatic shortcut: It converts an array to a pointer to the first element of the array. When arr1 appears in most contexts, it is changed automatically to &arr1[0]. There is not a huge philosophical reason for this; it is just a convenience for the ways we often use arrays. So ptr = arr1; would be equivalent to ptr = &arr1[0];, which is also not allowed. In this form, you can see that arr1 has become a pointer to an int, so you cannot assign it to a pointer to an array of int. Even though the pointer has the value you want, it is the wrong type.

When an array appears as the operand of & or sizeof or _Alignof, this automatic conversion does not occur. So &arr1 results in the address of the array.

A string literal that is used in an initialization such as char a[] = "abc"; is treated specially and is not automatically converted as described above.

Upvotes: 0

eq-
eq-

Reputation: 10096

In most contexts, an expression with an array type is implicitly converted to a pointer to the first element of such array, as explained by 6.3.2.1p3:

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type array of type is converted to an expression with type pointer to type that points to the initial element of the array object and is not an lvalue.

Thus the right-hand side of your assignment

ptr = arr1;

is implicitly converted to an incompatible pointer type (int* vs. int (*)[3]), and can't be stored to the pointer variable without a cast.

This isn't really an exception to any rule, as you need to use the unary & operator with other types, too:

T val, *ptr;
ptr = &val;

Upvotes: 3

Daniel Fischer
Daniel Fischer

Reputation: 183878

In

ptr = arr1;

arr1 is converted to an int*, so you're trying to assign from an incompatible pointer type. &arr1[0] is directly an int*, without conversion, so again incompatible.

&arr1 == arr1 == &arr1[0]

is wrong, since the entities have different types. They only point to the same address, so when printing out, they give the same result.

Upvotes: 5

Related Questions