...
UB | Description | |||
---|---|---|---|---|
Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object. | ||||
Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that points just beyond the array object and is used as the operand of a unary | ||||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c6213484f8215ae2-34d818a0-49b9495c-a2e997d9-508607fbd74cc5404d3fb08e"><ac:plain-text-body><![CDATA[ | [46 | CC. Undefined Behavior#ub_46] | An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression | ]]></ac:plain-text-body></ac:structured-macro> |
An attempt is made to access, or generate a pointer to just past, a flexible array member of a structure when the referenced object provides no elements for that array. |
...
This compliant solution is for illustrative purposes and is not necessarily the solution implemented by Microsoft. This particular "solution" may not be correct, because there is no guarantee that a L'
is found.
'
Noncompliant Code Example (Apparently Accessible Out Of Range Index)
Wiki Markup |
---|
The noncompliant example below declares {{matrix}} to consist of 7 rows and 5 columns in row-major order. The function {{init_matrix}} then iterates over all 35 elements in an attempt to initialize each to the value given by the function argument {{x}}. However, since multidimensional arrays are declared in C in row-major order and the function iterates over the elements in column-major order, when the value of {{j}} reaches the value {{COLS}} during the first iteration of the outer loop the function attempts to access element {{matrix\[0\]\[5\]}}. Since the type of {{matrix}} is {{int\[7\]\[5\]}}, the {{j}} subscript is out of range and the access has undefined behavior [46|CC. Undefined Behavior#ub_46]. |
Code Block | ||
---|---|---|
| ||
static const size_t COLS = 5;
static const size_t ROWS = 7;
static int matrix[ROWS][COLS];
void init_matrix(int x) {
for (size_t i = 0; i != COLS; ++i)
for (size_t j = 0; j != ROWS; ++j)
matrix[i][j] = x;
}
|
Compliant Solution
The compliant solution below takes care to avoid using out-of-range indices by initializing matrix
elements in the same row-major order as multidimensional objects are declared in C.
Code Block | ||
---|---|---|
| ||
static const size_t COLS = 5;
static const size_t ROWS = 7;
static int matrix[ROWS][COLS];
void init_matrix(int x) {
for (size_t i = 0; i != ROWS; ++i)
for (size_t j = 0; j != COLS; ++j)
matrix[i][j] = x;
}
|
Automated Detection
The Coverity Prevent Version 5.0 ARRAY_VS_SINGLETON checker can detect the access of memory past the end of a memory buffer/array. The NEGATIVE_RETURNS checker can detect when the loop bound may become negative. The OVERRUN_STATIC and OVERRUN_DYNAMIC checker can detect the out of bound read/write to array allocated statically or dynamically.
...