1

I understand how an array would decay into a pointer to the first element under certain circumstance.

I know that int array[] = {1,2,3,4,5} creates an array and that we can create a pointer int *ptr = array that after the assignment, also points to the first element of the array.

The thing is, what would happen when I do:int *ptr = {1,2,3,4,5}?

I tried printf("%d",ptr),printf("%d",ptr+1) and printf("%d",ptr+2) and it returns 1,5 and 9 respectively.

I tried printf("%d",*ptr) and it returns a segmentation fault

So I see that ptr points to the array {1,2,3,4,5}, and again tried:

for(int i=0;i<5;i++){
    printf("%d",(*p)[i]);
}

and it returns subscripted value is neither array nor pointer nor vector

Then I googled and can't really find what I am looking for.

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
Sam Chan
  • 510
  • 1
  • 8
  • 20
  • 2
    `int *ptr = {1,2,3,4,5};` it should not compile. A good compiler should warn you `error: excess elements in scalar initializer ` – Michi Feb 22 '18 at 10:52

4 Answers4

6

Using decent compilation flags gives the answer right away:

main.cpp:1:13: error: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' [-Werror,-Wint-conversion]
int *ptr = {1,2,3,4,5};
            ^
main.cpp:1:15: error: excess elements in scalar initializer [-Werror]
int *ptr = {1,2,3,4,5};
              ^

You are implicitly converting 1 to an int *, and throwing away the superfluous initializers.

Pointer arithmetic, done in multiples of sizeof(int) (here 4), is what produces 5 and 9.

Quentin
  • 62,093
  • 7
  • 131
  • 191
4

Yes ptr+1 basically does a pointer arithmetic and in your case sizeof(int) seems to be 4. That's why the resuts are 1+4 and 1+2*4 respectively.

Pointer arithmetic is dictated by the object it points to which is int here. And pointer moves by sizeof(int) that's why.

Also notice another thing, you have used brace enclosed initializer which generated the warning for multiple parameters inside {}. And ptr is initialized by 1 in this case. The behavior upon doing this is not defined but in your case it seems to be taking the first value in the list.

printf("%d",*ptr) is trying to read the what is there in the address pointed by ptr. In your case this generated segmentation fault - that means you tried to read a memory that you don't have permission to or you don't have access to.

To push you toward right direction, you can do this:-

int a[5]={1,2,3,4,5};
int *ap = a;
for(size_t i = 0; i < sizeof(a)/sizeof(a[0]); i++)
   // work with ap[i].
int (*p)[5] = &a;
for(size_t i = 0; i < sizeof(a)/sizeof(a[0]); i++)
   // work with (*p)[i]
user2736738
  • 30,591
  • 5
  • 42
  • 56
4

This statement

int *ptr = {1,2,3,4,5};

is having undefined behavior. An undefined behavior includes it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.

When compiling program having this statement - int *ptr = {1,2,3,4,5}, the compiler must be giving a warning message -

warning: excess elements in scalar initializer
int *ptr = {1,2,3,4,5};
              ^

Arithmetic types and pointer types are collectively called scalar types.

From C Standards#6.7.9p11:

The initializer for a scalar shall be a single expression, optionally enclosed in braces. ..

Giving more than one initializer to a scalar is undefined behavior.
From C Standards#J.2 Undefined behavior:

The initializer for a scalar is neither a single expression nor a single expression enclosed in braces

H.S.
  • 11,654
  • 2
  • 15
  • 32
3

The definition

int *ptr = {1,2,3,4,5};

is equivalent to

int *ptr = 1;

The rest of the initializers are invalid, and most definitely doesn't make it an array.

If you want to have a pointer to an array without actually defining one, you could use compound literals:

int *ptr = (int[]){1, 2, 3, 4, 5};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621