The C standard allows an array variable to be declared both with a dimension index and with an initialization literal. The initialization literal also implies an array size, in the number of elements specified.
The size implied by an initialization literal is usually specified by the number of elements:
int array[] = {1, 2, 3}; /* 3-element array */ but one can use designators to initialize array elements in a non-contiguous fashion. section 6.7.8 "initialization": {quote} EXAMPLE 12 Space can be "allocated" from both ends of an array by using a single designator:
int a[MAX] =
In the above, if MAX is greater than ten, there will be some zero-valued elements in the middle; if it is less than ten, some of the values provided by the first five initializers will be overridden by the second five.
C99 also dictates how array initialization is handled when the number of initialiation elements does not equal the explicit array demsnion. From Section 6.7.8 "Initialiation", paragraph 21:
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
and paragraph 22:
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. At the end of its initializer list, the array no longer has incomplete type.
So while C can compute the size of an array based on its initialization list, we recommend specifying the size of the array explicitly. This provides a redundancy check that the array's size is correct. It also enables compilers to emit warnings if the array's size is less than the size implied by the initialization.
Note that this advice does not apply to character arrays initialized with string literals, see [STR36-C. Do not specify the dimension of a character array initialized with a string literal] for more information.
Non-Compliant Code Example (Incorrect Size)
The following non-compliant code initializes an array of integers using an initialization with too many elements for the array.
int a[3] = {1, 2, 3, 4};
The size of the array a
is three, although the size of the initialization is four. The last element of the initialization (4
) is ignored.
This code will generate a warning in gcc
.
Non-Compliant Code Example (Implicit Size)
The following non-compliant code initializes an array of integers using an initialization with too many elements for the array.
int a[] = {1, 2, 3, 4};
The compiler will correctly assume an array size of 4. But if the initializer ever changes, the array size might change, cuasing unexpected results.
Compliant Solution
This compliant solution specifies the dimension of the array correctly.
int a[4] = {1, 2, 3, 4};
This is the preferred approach, because a programmer who changes the initializer size will be warned by the compiler that the array index should also change to accommodate the initializer.
Risk Assessment
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ARR02-A |
medium |
unlikely |
low |
P6 |
L2 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[ISO/IEC 9899:1999]]
[!CERT C Secure Coding Standard^button_arrow_left.png!] [!CERT C Secure Coding Standard^button_arrow_up.png!] [!CERT C Secure Coding Standard^button_arrow_right.png!]