2

Why does the sizeof operator produces 12 bytes when it should only be 4? When I reference the variable array, that is only referring to the memory address of the first index of the array. In fact, I printed the memory address of the first index &array[0] and compared it to array, they produced the same memory address result which confirms that they are both referring to the first index of the array, but 'array' produces 12 byte while array[0] produces 4 byte.

int main() {
int array[] = {1,2,3};
int a = 1;
int b = sizeof(array); //this is referring to the first index of the array
int c = sizeof(array[0]); //this is also referring to the first index of the array

std::cout << b << std::endl;
std::cout << array << std::endl; //they have the same memory address
std::cout << &array[0] << std::endl; /* they have the same memory address, which confirms that array 
and &array[0] is the same */

return 0;
}
dbush
  • 162,826
  • 18
  • 167
  • 209
Renz Carillo
  • 136
  • 7
  • 7
    `sizeof(array); //this is referring to the first index of the array` Why do you assume that? `array` is the name of an array. An arrays size is its number of elements times the size of an element. – NathanOliver Apr 16 '21 at 12:31
  • 3
    `array` -> `int[3]`. `array[0]` -> `int` – Ayxan Haqverdili Apr 16 '21 at 12:31
  • 2
    If `foo` is a function, then `array` in the expression `foo(array)` decays to a pointer to its first element. But `sizeof(array)` is not a function call. You can remind yourself of that fact by using the idiom `sizeof array`. When you omit the parentheses, it is far more difficult to confuse `sizeof` for a function call. – William Pursell Apr 16 '21 at 12:35
  • 2
    In **most** contexts, the name of an array decays into a pointer to its first element. `sizeof` is one of the exceptions; `array` refers to the **entire** array, which has 3 elements of type `int`. – Pete Becker Apr 16 '21 at 12:39
  • @NathanOliver then why does array+1 refers to the second index of the array? if array+1 refers to the 2nd index and array+2 refers to the third index, array must be referring to the first index, right? – Renz Carillo Apr 16 '21 at 13:07
  • 1
    @RenzCarillo Give this a read: https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay – NathanOliver Apr 16 '21 at 13:19
  • @RenzCarillo when you do `array+1` the array decays into a pointer. When you do `sizeof(array)` it doesn't. – DarkAtom Apr 19 '21 at 00:08

3 Answers3

5

Arrays and pointers are not the same, and this is a prime example of this.

In most contexts, an array decays to a pointer to its first member. One of the few times this decay does not happen is when the array is the subject of the sizeof operator. In that case it refers to the entire array and the expression evaluates to the size of the entire array in bytes.

This is described in section 6.3.2.1p3 of the C standard:

Except when it is the operand of the sizeof operator, the _Alignof operator, or theunary & 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. If the array object has register storage class, the behavior is undefined.

As well as the C++11 standard in sections 7.2:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The temporary materialization conversion (7.4) is applied. The result is a pointer to the first element of the array.

And 8.3.3p4:

The lvalue-to-rvalue (7.1), array-to-pointer (7.2), and function-to-pointer (7.3) standard conversions are not applied to the operand of sizeof. If the operand is a prvalue, the temporary materialization conversion (7.4)is applied.

So what we actually have is:

int b = sizeof(array);     // size of the entire array
int c = sizeof(array[0]);  // size of the first element of the array
int d = sizeof(&array[0]); // size of a pointer to an array element
dbush
  • 162,826
  • 18
  • 167
  • 209
4

The size of the array is 12 bytes. The output is correct. The size of the element is 4 bytes. There are 3 elements. 4 * 3 = 12.

In fact, i printed the memory address of the first index (&array[0]) and compared it to (array), they produced the same memory address result which confirms that they are both referring to the first index of the array

Just because the array has the same memory address as the first element of the array, doesn't mean that the entire array is contained within the first element. It isn't.


then why does array+1 refers to the second index of the array?

Because in such a sub expression, the array is implicitly converted to a pointer to first element, and adding 1 to a pointer to first element results in a pointer to second element. Such implicit conversion is called decaying.

eerorika
  • 181,943
  • 10
  • 144
  • 256
  • I thought there is no way to select the whole array? When we call the variable array, i thought it would only be referring to the first index – Renz Carillo Apr 16 '21 at 12:33
  • @RenzCarillo What do you mean by "call" an array. – eerorika Apr 16 '21 at 12:34
  • @RenzCarillo Along with the VLA extension (assuming C++, in C it is an optional part of the standard and mandatory in C99) comes the ability to check the size of the VLA too, but it happens at runtime. – mediocrevegetable1 Apr 16 '21 at 12:34
  • int array[]; //we are calling the array – Renz Carillo Apr 16 '21 at 12:35
  • @RenzCarillo: Also, what do you mean by "select" the whole array? Note that you've tagged the question both C and C++, and those are different languages. – MSalters Apr 16 '21 at 12:35
  • @RenzCarillo you don't call the array with `int array[]`, you **declare** `array` as an array of``int`s. – mediocrevegetable1 Apr 16 '21 at 12:36
  • @MSalters with sizeof(array); producing 12 bytes meaning it selects the whole array which contains 3 integers – Renz Carillo Apr 16 '21 at 12:36
  • 6
    @RenzCarillo An array is different from a pointer to the first element of an array. These two can be easily confused, because arrays really really like to turn into pointers to their first element. And the confusion is further aggravated by array type function arguments, which are inherited from C, are terrible and are actually pointers in disguise. But in reality `array` has no cause to turn into a pointer here, so it is the name of a whole `int[3]` here, not the name of a `int*`. – François Andrieux Apr 16 '21 at 12:39
0

If I understand your question well, on 64 bit machine int will be 4 bytes so the sizeof operator will return 3 x 4 = 12 bytes. Did not understand your assumption why it should return 4 in first place when you allocated only three items in that array.

If you want to know the number of items in the array you may do something as follows:

// Finds size of array[] and stores in 'size' int size = sizeof(array)/sizeof(array[0]);

DeepakP
  • 16
  • 2