CERT C++: MEM54-CPP

Обеспечьте размещение нового с правильно выровненными указателями на достаточную емкость хранилища

Описание

Определение правила

Обеспечьте размещение нового с правильно выровненными указателями на достаточную емкость хранилища[1]

Реализация Polyspace

Этот чекер проверяет, используется ли новое размещение с недостаточным хранением или несовпадающими указателями.

Примеры

расширить все

Проблема

Размещение нового используемого с недостаточным объемом памяти или несовпадающими указателями происходит, когда указатель передается в new размещения оператор не имеет достаточного объема памяти для выделения памяти или не выровнен должным образом.

Предположим, что указатель ptr предварительно выделено m байты памяти в стеке и имеет n выравнивания. Для образца, если ptr массив:

uint8_t ptr[5];
выделенное хранилище sizeof(uint8_t) * 5 и выравнивание alignof(uint8_t). Если вы выделяете больше m байты на этот указатель в new размещения выражение или если выравнивание, необходимое для выделения, больше nШашка вызывает нарушение. При определении выравнивания указателя на шашку учитываются явные выравнивания, такие как с std::align.

Средство проверки не рассматривает указатели, которые являются предварительно выделенной памятью на куче, поскольку доступное хранилище зависит от доступности памяти, которая известна только во время выполнения.

Риск

The new оператор выделяет необходимый объем памяти для хранения объекта на куче и создает новый объект в выделенной памяти за одну операцию. Если вы хотите разделить выделение и конструкцию и поместить объект в предварительно выделенную память или в стек, или в кучу, вы используете размещение new. Размещение new имеет преимущества перед new в определенных ситуациях, например, когда необходимо поместить объект в известное место памяти.

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

Зафиксировать

Убедитесь, что указатель используется в new размещения операция имеет достаточную память для выделения, и выравнивания совпадают.

Пример - new размещения Используется с недостаточной емкостью памяти и несовпадающими указателями
#include <new>
#include<memory>
#include <cstdint>

void Foo()
{
  uint8_t c;                
  uint64_t* ptr =
      new    // Non-compliant (insufficient storage, misaligned)
      (&c) uint64_t;
}

void Bar()
{
  uint8_t buf[sizeof(uint64_t)];    
  uint64_t* ptr =
      new            // Non-compliant (sufficient storage, misaligned)
      (buf) uint64_t;
}

void Baz()
{
  void* buf;
  std::size_t sp = 64;
  std::align(alignof(uint64_t), sizeof(uint64_t), buf, sp);
  uint64_t* ptr =
      new            // Compliant (sufficient storage, aligned)
      (buf) uint64_t;
}

В функциональном Foo, а &c указывает на uint8_t и имеет одну байтовую память в стеке с однобайтовым выравниванием. Указатель передается в new размещения, который создает образец uint64_t для этого требуется 8 байт памяти и 4-байтовое выравнивание. Это использование нарушает правило.

В функциональном Bar, указатель buf правильно выделен и имеет достаточную емкость для хранения. Но, потому что это указывает на uint8_t тип данных, он имеет однобайтовое выравнивание. Это использование все еще нарушает правило.

Функция Baz вызывает std::align функция для создания указателя с правильной емкостью памяти (8 байт) и выравниванием (4 байта) для uint64_t. Это использование соответствует правилу.

Проверяйте информацию

Группа: 06. Управление памятью (MEM)
Введенный в R2020b

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.