Я хотел бы перегрузить глобальные и неглобальные операторы new / delete для регистрации.
Поскольку я просто хочу добавить информацию о протоколировании, я бы хотел сохранить стандартное поведение этих операторов.
Есть ли способ перегрузить оператор new / delete для добавления регистрации, но без необходимости переписывать стандартное поведение (которое может быть подвержено ошибкам)?
На самом деле, мне нужно не только стандартное поведение. Мне нужно то же поведение, что и в реализациях Visual 2010, которые могут быть нестандартными.
Тип ошибки, которую я ищу с этим типом регистрации, является новым [] / delete несоответствие.
Я мог бы использовать классические инструменты, но они замедляют выполнение, и я хотел бы поделиться двоичным файлом с другими людьми, чтобы собрать больше информации.
Ты можешь использовать malloc
/free
для основного распределения. Обработка полная
соответствие стандартам для new
немного сложнее; вам нужно что-то вроде:
void*
operator new( size_t n )
{
void* results = malloc( n );
while ( results == NULL ) {
if ( std::get_new_handler() == NULL ) {
throw std::bad_alloc();
}
(*std::get_new_handler())();
results = malloc( n );
}
return results;
}
Однако часто вам не нужно такое полное соответствие. Если вы говорите, что
Вы не поддерживаете настройку new_handler
Например, вы можете
значительно упростить В перегруженной версии я использую для тестирования, по сути,
если malloc
действительно терпит неудачу, я прерываю (но эта версия имеет варианты
вызвать сбой new
, по требованию, так как я хочу проверить, что мой код
правильно реагирует и на это).
Если вы регистрируетесь, будьте очень осторожны, чтобы избежать бесконечной рекурсии. Единственный
функции гарантированно не использовать operator new
в стандартной библиотеке
являются malloc
а также free
, Конечно, у многих нет причин выделять
динамически, и я не беспокоюсь о таких функциях, как memcpy
или же
strlen
, На практике вы, вероятно, в безопасности с любой из функций
в библиотеке C (хотя в теории, printf
может быть реализовано в
условия iostream
). Но любое использование iostream, локали или стандарта
контейнеров нет, если вы не защищаете от рекурсии:
void*
operator new( size_t n )
{
static int recursionCount = 0;
++ recursionCount;
void* results = malloc() ;
// Any additional logic you need...
if ( recursionCount == 1 ) {
logAllocation( results, n );
}
-- recursionCount;
return results;
}
Формально вы должны сделать то же самое для operator delete
хотя в
на практике, если вы входите в файл, я не ожидал delete
кроме как в close()
или деструктор.
Вы можете переопределить new
ключевое слово для вызова другой подписи и передачи __FILE__
и тому подобное.
В общем случае это работает хорошо. Когда вы начинаете использовать объекты, которые переопределяют operator new
хотя ты как бы ввернешься.
Если бы я знал это по памяти, я бы поделился, но вы, вероятно, можете найти с Google. Я думаю, что где-то есть реализация кода проекта.