exponenta event banner

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 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

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

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