Описание
Неправильное масштабирование указателя происходит, когда 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;
}