CERT C++: MEM57-CPP

Избегайте использования оператора по умолчанию, нового для сверхвыровненных типов

Описание

Управляйте определением

Избегайте использования оператора по умолчанию, нового для сверхвыровненных типов. [1]

Реализация Polyspace

Это средство проверки проверяет на Оператор, новый не перегруженный для возможно сверхвыровненного класса.

Примеры

развернуть все

Проблема

Оператор, новый не перегруженный для возможно сверхвыровненного класса, происходит, когда вы не соответственно перегружаете оператор new/new[] и вы используете этот оператор, чтобы создать объект с требованием выравнивания, заданным с alignas. Средство проверки повышает дефект для этих версий броска и неброска оператора new/new[].

  • void* operator new(std::size_t size)

  • void* operator new(std::size_t size, const std::nothrow_t&)

  • void* operator new[](std::size_t size)

  • void* operator new[](std::size_t size, const std::nothrow_t&)

Использование alignas указывает, что вы не ожидаете оператор по умолчанию new/new[] удовлетворить требованию выравнивания или объекту, и что объект возможно по выровненному. Тип по выровненному, если вы используете alignas сделать требование выравнивания типа больше, чем std::max_align_t. Например, foo по выровненному в этом фрагменте кода, потому что его требование выравнивания составляет 32 байта, но std::max_align_t имеет выравнивание 16 байтов в большинстве реализаций.

struct alignas(32) foo {
  char elems[32];
}

Оператор, новый не перегруженный для возможно сверхвыровненного класса, не повышает дефекта, если вы не перегружаете оператор new/new[] и вы используете версию C++ 17 или позже Стандарта. Оператор по умолчанию new/new[] на C++ 17 или более поздние поддержки по выравниванию путем передачи требования выравнивания в качестве аргумента типа std::align_val_t, например, void* operator new(std::size_t size, std::align_val_t alignment).

Риск

Оператор по умолчанию new/new[] выделяет устройство хранения данных с требованием выравнивания std::align_val_t самое большее. Если вы не перегружаете оператор, когда вы создаете объект с по выровненному типу, полученный объект может быть неправильно выровнен. Доступ к этой объектной силе вызывает ошибки несанкционированного доступа или аварийные завершения программы.

Фиксация

Если вы используете версию C++ 14 или ранее Стандарта, передаете требование выравнивания по выровненным типам к оператору new/new[] путем перегрузки оператора.

Пример - выделенная память меньше, чем требование выравнивания типа foo

#include <new>
#include <cstdlib>
#include <iostream>

struct alignas(64) foo {
    char elems[32];
};

foo*  func()
{
    foo*  bar = 0x0;
    try {
        bar =  new  foo ;
    } catch (...) { return nullptr; }
    delete bar;
}

В этом примере, структура foo объявляется с требованием выравнивания 32 байтов. Когда вы используете оператор по умолчанию new создать объект bar, выделенная память для bar меньше, чем требование выравнивания типа foo и bar может быть неправильно выровнен.

Коррекция — задает перегруженный оператор new обрабатывать требование выравнивания типа foo

Одна возможная коррекция, если вы используете C11 stdlib.h или POSIX-C malloc.h, должен задать перегруженный оператор new это использует aligned_alloc() или posix_memalign() или получить устройство хранения данных с правильным выравниванием.

#include <new>
#include <cstdlib>
#include <iostream>

struct alignas(64) foo {
    char elems[32];
    static void* operator new (size_t nbytes)
    {
        if (void* p =
                ::aligned_alloc(alignof(foo), nbytes)) {
            return p;
        }
        throw std::bad_alloc();
    }
    static void operator delete(void *p) {
        free(p);
    }
};

foo*  func()
{
    foo*  bar = 0x0;
    try {
        bar =  new  foo ;
    } catch (...) { return nullptr; }
    delete bar;
} 

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

Группа: правило 06. Управление памятью (MEM)

Введенный в R2019b


[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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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