Top.Mail.Ru
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V102. Usage of non memsize type for...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V102. Usage of non memsize type for pointer arithmetic.

15 Дек 2011

Анализатор обнаружил потенциально возможную ошибку в адресной арифметике с указателями. Ошибка может заключаться в переполнении при вычислении выражения.

Рассмотрим пример.

short a16, b16, c16;
char *pointer;
...
pointer += a16 * b16 * c16;

Данный пример корректно работает с указателями, если значение выражения "a16 * b16 * c16" не превышает 'INT_MAX' (2Гб). Такой код мог всегда корректно работать на 32-битной платформе, в силу того, что программа никогда не выделяла массивов больших размеров. На 64-битной архитектуре программиста, использующего старый код для работы с массивом большего размера, ждет разочарование. Допустим, мы хотим сдвинуть значение указателя на 3000000000 байт, и по этому переменные 'a16', 'b16' и 'c16' имеют значения 3000, 1000 и 1000 соответственно. При вычислении выражения "a16 * b16 * c16" все переменные, согласно правилам языка Си++, будут приведены к типу int, а уже затем будет произведено их умножение. В ходе выполнения умножения, произойдет переполнение, в результате которого будет получено число -1294967296. Некорректный результат выражения будет расширен до типа 'ptrdiff_t' и произойдет вычисление указателя. В результате нас будет ожидать аварийное завершение программы, при попытке использования некорректного указателя.

Для предотвращения подобных ошибок следует использовать memsize типы. В нашем случае будет корректно заменить типы переменных 'a16', 'b16', 'c16' или использовать их явное приведение к типу 'ptrdiff_t', как показано ниже:

short a16, b16, c16;
char *pointer;
...
pointer += static_cast<ptrdiff_t>(a16) *
      static_cast<ptrdiff_t>(b16) *
      static_cast<ptrdiff_t>(c16)

Хочется отметить, что не всегда использование в арифметике с указателями не memsize типов является ошибочным. Рассмотрим следующую ситуацию:

char ch;
short a16;
int *pointer;
...
int *decodePtr = pointer + ch * a16;

Анализатор не выдает на нее сообщения, в силу ее корректности. Здесь не происходит вычислений, которые могли бы привести к переполнению и результат этого выражения всегда будет корректен как на 32-битной, так и на 64-битной платформе.

Дополнительные материалы по данной теме:

close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Я хочу принять участие в тестировании
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам