Does the C standard require that the size of an array of n elements be n times the size of an element, either by explicit statement or by rigorous logical deduction from its requirements?
For example, could int (*x)[5] = malloc(5 * sizeof **x);
fail to request sufficient space for an array of five int
?
C 2011 [N1570] 6.5.3.4 7 shows an example of computing the number of elements in an array as sizeof array / sizeof array[0]
. However, examples are not a normative part of the standard (per paragraph 8 of the forward).
6.2.5 20 says an array type describes a contiguously allocated nonempty set of objects with a particular type but is silent about the total memory required.
This is solely a language-lawyer question; actual implementations are irrelevant. (To appease those who want concrete examples, hypothesize a C implementation that requires additional memory management for large arrays, so creating an array requires creating some additional data to help manage the memory.)
You can declare an array without a size specifier for the leftmost dimension in multiples cases: as a global variable with extern class storage (the array is defined elsewhere), as a function parameter: int main(int argc, char *argv[]) . In this case the size specified for the leftmost dimension is ignored anyway.
To determine the size of your array in bytes, you can use the sizeof operator: int a[17]; size_t n = sizeof(a); On my computer, ints are 4 bytes long, so n is 68. To determine the number of elements in the array, we can divide the total size of the array by the size of the array element.
The MINIMUM limit is an array of 1 element.
We need to give the size of the array because the complier needs to allocate space in the memory which is not possible without knowing the size.
Yes, it is required that the size of an array T[n]
be n * sizeof (T)
.
The Standard defines arrays in §6.2.5/20:
An array type describes a contiguously allocated nonempty set of objects with a particular member object type....
Further, the sizeof
operator yields the total number of bytes in the array(§6.5.3.4/4):
When sizeof is applied .... to an operand that has array type, the result is the total number of bytes in the array. When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.
Since an array consists of a contiguous allocation of objects, there can be no internal padding. And since trailing padding is mentioned explicitly with respect to the sizeof
operator only in the context of unions and structures, it seems clear that arrays are expected to possess no such trailing padding.
Finally, note that in §6.2.6.1/4 is stated:
Values stored in non-bit-field objects of any other object type consist of n x CHAR_BIT bits, where n is the size of an object of that type, in bytes. The value may be copied into an object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes is called the object representation of the value.
Supposing that arrays could have trailing padding bytes, consider an array unsigned char A[n]
, and further consider the array unsigned char B[sizeof A]
, to which all of the bytes (including possible padding bytes) of A[]
have been copied. Now, A[]
must be the same size as B[]
, since (§6.2.6.1/8):
Where an operator is applied to a value that has more than one object representation, which object representation is used shall not affect the value of the result.
This would mean that B[]
must have no trailing padding, which would mean that arrays can have trailing padding bytes except under certain special conditions which are nowhere mentioned in the Standard, or alternatively that arrays may have trailing padding except for arrays of unsigned char
. Since neither of these possibilities is mentioned in the Standard, it seems reasonable to conclude that arrays must not have trailing padding in the first place.
The only text describing the representation of arrays is quite terse, and is in what you found at 6.2.5 ¶20:
Any number of derived types can be constructed from the object and function types, as follows:
- An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. The element type shall be complete whenever the array type is specified. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T , the array type is sometimes called ''array of T ''. The construction of an array type from an element type is called ''array type derivation''.
Note that it does not say something like "contiguously allocated nonempty set of objects and padding", so the array is just the objects. Thus there seems to be no basis for a claim that sizeof
the array [type] could yield any result other than the size of the contiguous set of objects, which is obviously N
times the size of the individual element type.
It's also worth noting that padding is not something that can just exist on its own because it's not specified not to exist. C specifies representations of types (6.2.6) and explicitly specifies the possibility of padding bits and bytes where appropriate. There is no text about padding for arrays, and thus it's not part of their representation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With