exponenta event banner

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

Перегружена только одна функция в паре функций распределения-освобождения

Описание

Этот дефект возникает при перегрузке 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.

Примеры

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

#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); 
}

Информация о результатах

Группа: Надлежащая практика
Язык: C++
По умолчанию: Откл.
Синтаксис командной строки: MISSING_OVERLOAD_NEW_DELETE_PAIR
Воздействие: Низкий
Представлен в R2019a