V118. malloc() function accepts a dangerous expression in the capacity of an argument.
Анализатор обнаружил потенциальную ошибку, связанную с использованием опасного выражения, являющегося фактическим аргументом для функции malloc. Ошибка может заключаться в некорректных представлениях о размерах типов, заданных в виде числовых констант.
Анализатор считает подозрительными те выражения, в которых присутствуют константные литералы кратные четырем, но отсутствует оператор sizeof().
Пример первый.
Некорректный код выделения памяти для матрицы размером 3x3 из элементов типа size_t может выглядеть следующим образом:
size_t *pMatrix = (size_t *)malloc(36); // V118
Хотя такой код мог долгое время надежно работать в 32-битной системе, использование магического числа 36 некорректно. При компиляции 64-битной версии необходимо выделить уже 72 байта памяти. Исправление заключается в использовании оператора sizeof ():
size_t *pMatrix = (size_t *)malloc(9 * sizeof(size_t));
Второй пример.
Некорректен для 64-битной системы и следующий код, основанный на предположении, что размер структуры Item равен 12 байт:
struct Item {
int m_a;
int m_b;
Item *m_pParent;
};
Item *items = (Item *)malloc(GetArraySize() * 12); // V118
Исправление также заключается в использовании оператора sizeof() для корректного вычисления размера структуры:
Item *items = (Item *)malloc(GetArraySize() * sizeof(Item));
Приведенные ошибки просты и легки в исправлении. Но от этого они не менее опасны и сложны для поиска в больших приложениях. Именно поэтому диагностика подобных ошибок реализована в виде отдельного правила.
Наличие константы в выражении, являющегося параметром для функции malloc(), вовсе не означает, что на него всегда выдается предупреждение V118. Если в выражении участвует оператор sizeof(), то такая конструкция считается безопасной. Пример кода, считающийся анализатором безопасным:
int *items = (int *)malloc(sizeof(int) * 12);
Дополнительные материалы по данной теме:
- 64-битные уроки. Урок 9. Паттерн 1. Магические числа.