AUTOSAR C++14 Rule A18-5-10

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

Описание

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

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

Объяснение

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

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

Реализация Polyspace

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

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

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

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

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

#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. Это использование соответствует правилу.

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

Группа: Библиотека языковой поддержки
Категория: Необходимый, Автоматизированный
Введенный в R2020b