0

I'm learning pointers to (entire) arrays in C.

Suppose I declare a 2d matrix of ints:

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

Now, I declare a pointer of appropriate type:

int (*ptr)[3][3];

Initialize it:

ptr = &arr;

Now, ptr contains the address of arr.

  ptr --->&(arr[0][0]   arr[0][1]   arr[0][2]
            arr[1][0]   arr[1][1]   arr[1][2]
            arr[2][0]   arr[2][1]   arr[2][2])

So, when we dereference ptr, it should yield the first location, isn't it?

printf("%d", *ptr) gives an error at compile time. To print the first element, I've to use ***ptr.

I have 2 questions:

  1. I can't understand the need for a triple dereferencing.
  2. If *ptr doesn't point to first element of array, what does it point to?
2
  • 2
    Why would you expect *&arr to refer to arr[0][0] instead of arr? That's like expecting *&some_int to refer to the int's first byte, rather than the entire int. Commented Oct 25, 2015 at 5:55
  • I am confused because int is a primitive type whereas array is a collection of primitives. Printing the array will require looping over all it's elements, unlike an int. Commented Oct 25, 2015 at 7:54

1 Answer 1

2
printf(*ptr);

is wrong since the first argument to printf needs to be a string that specifies the format to use to print the rest of the arguments. To print the address, use:

printf("%p", *ptr);

I can't understand the need for a triple dereferencing.

The type of p is int (*)[3][3].

The type of *p is int [3][3].

The type of **p is int [3]

The type of ***p is int.

When you have a pointer like that, it's best to use the array syntax.

(*p)[0][0]

The generic form would be:

(*p)[i][j]

That is a lot less confusing than using ***p. Besides, ***p can be used to access the [0][0]-th element of the array only.

If *ptr doesn't point to first element of array, what does it point to?

Hopefully the answer to the previous question explains this.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your explanation! Got it.
%p expects void*. So you trigger UB. It should be printf("%p", (void*)*ptr);
@tstanisl, Any object pointer can be used where void* is expected. I don't understand why leaving out the explicit cast would cause UB.
@RSahu, because C standard does not require pointer types to have the same binary representation as void*. Serializing pointer of type int* and deserializing it as void* is not defined by the standard. Thus one must do a cast to be portable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.