CERT C++: DCL54-CPP

Функции выделения и отмены перегрузки как пара в одной возможности

Описание

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

Выделение и отмена перегрузки функционирует как пара в одной возможности.[1]

Реализация Polyspace

Эта проверка проверяет Отсутствующая перегрузка функции выделения или удаления.

Примеры

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

Проблема

Отсутствующая перегрузка функции выделения или удаления возникает, когда вы перегружаете operator new но не перегружайте соответствующий operator delete, или наоборот.

Риск

Обычно вы перегружаете operator new для выполнения некоторой бухгалтерии в дополнение к выделению памяти в свободном хранилище. Если вы не перегрузите соответствующий operator deleteВероятно, вы опускали некоторую соответствующую бухгалтерию при снятии памяти.

Дефект может также указывать на ошибку кодирования. Например, вы перегрузили форму размещения operator new[]:

void *operator new[](std::size_t count, void *ptr);
но непостановочная форма operator delete[]:
void operator delete[](void *ptr);
вместо формы размещения:
void operator delete[](void *ptr, void *p );

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

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

Например, в классе, если вы перегрузите форму размещения operator new:

class MyClass {
   void* operator new  ( std::size_t count, void* ptr ){
   //...
   }
};
Убедитесь, что вы также перегрузите форму размещения operator delete:
class MyClass {
   void operator delete  ( void* ptr, void* place ){
   ...
   }
};

Как найти operator delete соответствующий operator new, см. страницы с описанием для operator new и operator delete.

Пример - Несоответствие между перегруженными operator new и operator delete
#include <new>
#include <cstdlib>

int global_store;

void update_bookkeeping(void *allocated_ptr, bool alloc) {
   if(alloc) 
      global_store++;
   else
      global_store--;
}


void *operator new(std::size_t size, const std::nothrow_t& tag);
void *operator new(std::size_t size, const std::nothrow_t& tag) {
    void *ptr = (void*)malloc(size);
    if (ptr != nullptr)
        update_bookkeeping(ptr, true);
    return ptr;
}

void operator delete[](void *ptr, const std::nothrow_t& tag);
void operator delete[](void* ptr, const std::nothrow_t& tag) {
    update_bookkeeping(ptr, false);
    free(ptr); 
}

В этом примере операторы operator new и operator delete[] перегружены, но нет перегрузок соответствующих operator delete и operator new[] операторы.

Перегрузка operator new вызывает функцию update_bookkeeping для изменения значения глобальной переменной global_store. Если значение по умолчанию operator delete вызывается, эта глобальная переменная не затронута, что может бросить вызов ожиданиям разработчика.

Коррекция - перегрузка правильной формы operator delete

Если вы хотите перегрузить operator new, перегрузить соответствующую форму operator delete в тех же возможностях.

#include <new>
#include <cstdlib>

int global_store;

void update_bookkeeping(void *allocated_ptr, bool alloc) {
   if(alloc) 
      global_store++;
   else
      global_store--;
}


void *operator new(std::size_t size, const std::nothrow_t& tag);
void *operator new(std::size_t size, const std::nothrow_t& tag) {
    void *ptr = (void*)malloc(size);
    if (ptr != nullptr)
        update_bookkeeping(ptr, true);
    return ptr;
}

void operator delete(void *ptr, const std::nothrow_t& tag);
void operator delete(void* ptr, const std::nothrow_t& tag) {
    update_bookkeeping(ptr, false);
    free(ptr); 
}

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

Группа: 01. Объявления и инициализация (DCL)
Введенный в R2019a

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

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

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