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.

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

Риск

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

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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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