Описание
Неправильное масштабирование указателя происходит, когда Polyspace® Bug Finder™ полагает, что вы игнорируете неявное масштабирование в адресной арифметике с указателями.
Например, дефект может произойти в следующих ситуациях.
Ситуация | Риск | Возможная фиксация |
---|
Вы используете оператор sizeof в арифметических операциях на указателе. | Оператор sizeof возвращает размер типа данных в количестве байтов. Адресная арифметика с указателями уже неявно масштабируется размером типа данных резкой переменной. Поэтому использование sizeof в адресной арифметике с указателями приводит к непреднамеренным результатам. | Не используйте оператор sizeof в адресной арифметике с указателями. |
Вы выполняете арифметические операции на указателе, и затем применяете бросок. | Адресная арифметика с указателями неявно масштабируется. Если вы не полагаете, что это неявное масштабирование, бросая результат адресной арифметики с указателями приводит к непреднамеренным результатам. | Примените бросок перед адресной арифметикой с указателями. |
Фиксация
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
Пример - использование оператора sizeof
void func(void) {
int arr[5] = {1,2,3,4,5};
int *ptr = arr;
int value_in_position_2 = *(ptr + 2*(sizeof(int)));
}
В этом примере операция 2*(sizeof(int))
возвращает дважды размер переменной int
в байтах. Однако, потому что адресная арифметика с указателями неявно масштабируется, количеством байтов, которыми смещается ptr
, является 2*(sizeof(int))*(sizeof(int))
.
В этом примере неправильное масштабирование переключает ptr
вне границ массива. Поэтому ошибка Pointer access out of bounds появляется на операции *
.
Исправление — удаляет оператор sizeof
Одно возможное исправление должно удалить оператор sizeof
.
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;
}
В этом примере операция &x + 1
смещает &x
sizeof(int)
. После операции получившийся указатель указывает вне позволенного буфера. Когда вы разыменовываете указатель, ошибка Pointer access out of bounds появляется на операции *
.
Исправление — применяет бросок перед адресной арифметикой с указателями
Если вы хотите получить доступ к второму байту x
, сначала бросьте &x
к указателю char*
и затем выполните адресную арифметику с указателями. Получившийся указатель смещается байтами sizeof(char)
и неподвижными точками в позволенном буфере, размер которого является байтами sizeof(int)
.
int func(void) {
int x = 0;
char r = *((char *)(&x )+ 1);
return r;
}