V802. On 32-bit/64-bit platform, structure size can be reduced from N to K bytes by rearranging the fields according to their sizes in decreasing order.


Анализатор обнаружил конструкцию, которую потенциально можно оптимизировать. В коде программы имеется структура данных, которая может приводить к неэффективному использованию оперативной памяти.

Рассмотрим пример структуры, о которой анализатор сообщит как о неэффективной:

struct LiseElement {
  bool m_isActive;
  char *m_pNext;
  int m_value;
};

Данная структура в 64-битном коде займет 24 байта, что связано с выравниванием данных. Но если поменять последовательность полей, то ее размер составит всего 16 байт. Оптимизированный вариант структуры будет выглядеть так:

struct LiseElement {
  char *m_pNext;
  int m_value;
  bool m_isActive;
};

Конечно, перестановка полей не всегда возможна или необходима. Но если подобные структуры используются миллионами, то есть смысл задуматься об оптимизации расходуемой памяти. Дополнительно сокращение размера структур может повысить производительность приложения, так как при таком же количестве элементов, будет требоваться меньшее количество обращений к памяти.

Отметим, что приведенная структура всегда занимает 12 байт в 32-битной программе, в какой бы последовательности не располагались поля. Поэтому, при проверке 32-битной конфигурации, сообщение V802 выдано не будет.

Естественно бывают и обратные ситуации, когда размер структуры можно оптимизировать в 32-битной конфигурации и нельзя в 64-битной. Рассмотрим пример такой структуры:

struct T_2
{
  int *m_p1;
  __int64 m_x;
  int *m_p2;
}

Эта структура в 32-битной программе из-за выравнивания будет занимать 24 байта. Если же переставить поля, как показано ниже, то она будет занимать только 16 байт.

struct T_2
{
  __int64 m_x;
  int *m_p1;
  int *m_p2;
}

В 64-битной программе расположение полей в структуре 'T_2' не имеет значения. В любом случае она займет 24 байта.

Метод сокращения объема структур достаточно прост. Достаточно расположить поля в порядке убывания их размера. В этом случае поля начнут располагаться без лишних зазоров. Например, возьмем следующую структуру размером 40 байт в 64-битной программе:

struct MyStruct
{
  int m_int;
  size_t m_size_t;
  short m_short;
  void *m_ptr;
  char m_char;
};

Простой сортировкой последовательности полей по убыванию размера:

struct MyStructOpt
{
  void *m_ptr;
  size_t m_size_t;
  int m_int;
  short m_short;
  char m_char;
};

мы получим из нее структуру размером 24 байт.

Анализатор не всегда выдает сообщение о неэффективности структур, так как старается сократить количество излишних предупреждений. Например, анализатор не выдает предупреждение на сложные классы, являющимися наследниками, поскольку такие объекты обычно создаются в малом количестве. Пример:

class MyWindow : public CWnd {
  bool m_isActive;
  size_t m_sizeX, m_sizeY;
  char m_color[3];
  ...
};

Размер данной структуры может быть сокращен, но это не имеет практического смысла.


Найденные ошибки

Проверено проектов
354
Собрано ошибок
13 290

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;