2

The following declaration:

int (*x)[10]

is defined as x is an integer pointer to an integer array of 10 elements.

Question 1 : Doesn't this mean that x initially points to the first element of an array of 10 integers? If so, then, how is this different from the simple int x[10]?

Question 2 : If int (*x)[10] is different, then how is it different and what are some instances of its practical usage?

Question 3 : I was trying to write a simple program access, write to and print the array elements.

#include <stdio.h>

void main()
{
    int (*x)[12], i;
    for(i = 0; i <= 11;)
    {
        (*x)[i] = i;
        printf("%d\n", (*x)[i++]);
    }
}

I keep getting a segmentation fault when I run it. I understand that a segmentation fault occurs when I try to access memory that I don't have access to. But I am only accessing the 12 elements that I have initialized. Then why does my program exit with a segmentation fault? Also, am I accessing the array ((*x)[i] = i) correctly and are there other ways to access it?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
limbo1927
  • 55
  • 4
  • Which part in your learning material makes you assume they could be somehow the same? A pointer holds an address. An array holds multiple members. A pointer to an array holds the address of an array what contains multiple members. – Gerhardh Jul 07 '22 at 13:25
  • "x is an integer pointer to an integer array of 10 elements" Rather: x is a pointer to an array of 10 integer elements. – Lundin Jul 07 '22 at 13:38
  • "I was trying to write a simple program access, write to and print the array elements" There is no array in your program so you can't do that. In order to use a point to an array, you need an array to point at. You cannot "store data inside pointers", that doesn't make any sense. – Lundin Jul 07 '22 at 13:40
  • @Lundin I got confused by the [10] part. I assumed that (*x)[10] would automatically allocate memory for a 10 integer element array and x would point to its base address. – limbo1927 Jul 07 '22 at 14:15
  • "I assumed that (*x)[10] would automatically allocate memory for a 10 integer element array and x would point to its base address" How would that be different from `int x[10]` then? Because what you just described is the behavior of an ordinary array, which decays into a pointer to its first element when used in an expression. – Lundin Jul 07 '22 at 14:19
  • @Gerhardh When we do int x[10]; int *x_ptr; x_ptr = x; Then it means that x is pointing to the base element of array x. I got confused by int (*x)[10], because I assumed it allocates a 10 element array that isn't named and then x would point to its base address. I was wrong though, thanks for the clarification. – limbo1927 Jul 07 '22 at 14:20

1 Answers1

2

For starters according to the C Standard the function main without parameters shall be decalred like

int main( void )

In the shown program you declared an uninitialized pointer

int (*x)[12], i;

that has an indeterminate value. So dereferencing the pointer

(*x)[i] = i;

results in undefined behavior.

Instead you could write for example

#include <stdio.h>

int main( void )
{
    enum { N = 12 };
    int a[N];

    int (*x)[N] = &a;

    for ( size_t i = 0; i < N; i++ )
    {
        (*x)[i] = i;
        printf( "%d\n", (*x)[i] );
    }
}

Though the program will look simpler if to write it like

#include <stdio.h>

int main( void )
{
    enum { N = 12 };
    int a[N];

    int *x = a;

    for ( size_t i = 0; i < N; i++ )
    {
        x[i] = i;
        printf( "%d\n", x[i] );
    }
}

In this declaration

int *x = a;

is implicitly converted to a pointer to its first element of the type int *.

In this declaration

int (*x)[N] = &a;

the initializing expression &a is already a pointer of the type int ( * )[N].

So in the expression

(*x)[i] = i;

the subexpression *x yields lvalue of the array a. So in fact the above expression is equivalent to

a[i] = i;

Pay attention to that in the both declarations

int *x = a;

and

int ( *x )[N] = &a;

the pointers x store the starting address of the memory extent occupied by the array a but have different types. Dereferencing the first pointer you will get the first element of the array a. Dereferencing the second pointer you will get the whole array itself.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335