简体   繁体   中英

Why does the sizeof operator produce different results for an array

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;
}

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 NT” 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

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.

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]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM