Main Content

Incorrect pointer scaling

Implicit scaling in pointer arithmetic might be ignored

Description

This defect occurs when Polyspace® Bug Finder™ considers that you are ignoring the implicit scaling in pointer arithmetic.

For instance, the defect can occur in the following situations.

SituationRiskPossible Fix
You use the sizeof operator in arithmetic operations on a pointer.

The sizeof operator returns the size of a data type in number of bytes.

Pointer arithmetic is already implicitly scaled by the size of the data type of the pointed variable. Therefore, the use of sizeof in pointer arithmetic produces unintended results.

Do not use sizeof operator in pointer arithmetic.
You perform arithmetic operations on a pointer, and then apply a cast.Pointer arithmetic is implicitly scaled. If you do not consider this implicit scaling, casting the result of a pointer arithmetic produces unintended results.Apply the cast before the pointer arithmetic.

Fix

The fix depends on the root cause of the defect. See fixes in the table above and code examples with fixes below.

If you do not want to fix the issue, add comments to your result or code to avoid another review. See:

Examples

expand all

void func(void) {
    int arr[5] = {1,2,3,4,5};
    int *ptr = arr;

    int value_in_position_2 = *(ptr + 2*(sizeof(int)));
}

In this example, the operation 2*(sizeof(int)) returns twice the size of an int variable in bytes. However, because pointer arithmetic is implicitly scaled, the number of bytes by which ptr is offset is 2*(sizeof(int))*(sizeof(int)).

In this example, the incorrect scaling shifts ptr outside the bounds of the array. Therefore, a Pointer access out of bounds error appears on the * operation.

Correction — Remove sizeof Operator

One possible correction is to remove the sizeof operator.

void func(void) {
    int arr[5] = {1,2,3,4,5};
    int *ptr = arr;

    int value_in_position_2 = *(ptr + 2);
}
int func(void) {
    int x = 0;
    char r = *(char *)(&x + 1);
    return r;
}

In this example, the operation &x + 1 offsets &x by sizeof(int). Following the operation, the resulting pointer points outside the allowed buffer. When you dereference the pointer, a Pointer access out of bounds error appears on the * operation.

Correction — Apply Cast Before Pointer Arithmetic

If you want to access the second byte of x, first cast &x to a char* pointer and then perform the pointer arithmetic. The resulting pointer is offset by sizeof(char) bytes and still points within the allowed buffer, whose size is sizeof(int) bytes.

int func(void) {
    int x = 0;
    char r = *((char *)(&x )+ 1);
    return r;
}

Result Information

Group: Programming
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: BAD_PTR_SCALING
Impact: Medium

Version History

Introduced in R2015b