6

int array[] = {1,2,3,4};

As I understand, array is just a pointer to &array[0]

But how come then sizeof(array); knows size of an array and not just that it's only 4 byte number?

6
  • 3
    A good question. The answer is, of course, that array is not just a pointer. It just "decays" to one in the most frequently occuring contexts, namely on the right side of an assignment and as function arguments. Commented Oct 9, 2015 at 9:52
  • 3
    Another somewhat esoteric example is printf("%p == %p but %p != %p!\n", array, &array, array+1,&array+1);. I.e while array and &array have the same numerical values, they still have different types: &array is a pointer to, one wouldn't believe it, an array whose size is 4*sizeof(int), and consequently &array+1 advances the pointer by that size, e.g. 16 or 32 bytes. Commented Oct 9, 2015 at 10:30
  • How many times has 'an array is not a pointer' been posted here? Commented Oct 9, 2015 at 10:59
  • @PeterSchneider thanks alot your answer actually connected the dots for me . ! Commented Oct 9, 2015 at 11:20
  • @MartinJames I originally wanted to close as dup but then didn't find a post which exactly asks this question. (To be sure, it has been said millions of times, but mostly in the context of "why can I not assign" or "my program crashes here, why" etc.). Commented Oct 9, 2015 at 11:51

5 Answers 5

7

Although the name of the array does become a pointer to its initial member in certain contexts (such as passing the array to a function) the name of the array refers to that array as a whole, not only to the pointer to the initial member.

This manifests itself in taking the size of the array through sizeof operator.

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

2 Comments

With ordinary pointer arithmetics it doesn't show, only with multi dimensional arrays. Oh, and also if you take the address of the array; I think that's what you meant. Correct.
@PeterSchneider Thank you for the comment! I removed the part where I talk about pointer arithmetics to avoid confusion, because the rules remain the same, as long as the pointer is of proper type.
4

Except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T, and the value of the expression will be the address of the first element of the array.

Arrays in C don't store any metadata about their size or anything else, nor is any storage set aside for any sort of pointer. They're laid out pretty much as follows:

     +---+
arr: | 1 | arr[0]
     +---+
     | 2 | arr[1]
     +---+
     | 3 | arr[2]
     +---+
     | 4 | arr[3]
     +---+

There's no separate storage for a variable arr apart from the array elements themselves. As you can see, the address of arr and the address of arr[0] are the same. This is why the expressions arr, &arr, and &arr[0] all give you the same value (the address of the first element), even though the types of those expressions are different.

Except when the operand is a variable-length array, the result of sizeof is computed at compile time, and the compiler treats array operands as arrays in those circumstances; otherwise, it treats the array expression as a pointer to the first element.

1 Comment

I would argue that the value of arr is all 4 elements. It is just that printf (or anybody else, for that matter) cannot see that because it just receives the pointer after the argument passing. Admittedly the argument is bordering on ontology.
0

No, array is not just a pointer, as your sizeof example shows. It is only that in most contexts, it is converted to &array[0], but not in all.

Comments

0

This does only work within the scope where you define the array. If you pass your array to a function the sizeof operator doesn't work anymore. I'm not completely sure but I think that the compiler stores the length of the array and puts it back where you have sizeOf(array) like a macro but not dynamically. Please correct me if someone knows better.

1 Comment

That used to be the case before the advent of variable length arrays: sizeof() was known at compile time and as such acted like an int literal. It still is true for "normal" arrays. sizeof() of a variable length array, by contrast, must be computed at run time because it is only known at run time.
0

In this declaration -

int a[] = {1,2,3,4};    // a is of array type 

a becomes a pointer to first element of array a ( after decay ). Not in all cases both will be equal , but in cases such as when array is passed to function .

Comments

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.