Чтобы определить собственные функции new и delete для отслеживания распределения памяти в C++, можно следовать таким рекомендациям:
- Собрать информацию о том, как программа использует динамическую память. 1 Нужно понять, как распределены выделяемые блоки по размерам, как распределяется их время жизни, порядок выделения и освобождения. 1
- Определить функции в глобальной области видимости или как функции-члены. 4 Когда компилятор встречает выражение new или delete, он ищет соответствующую вызову функцию оператора. 4 Если резервируемый (освобождаемый) объект имеет тип класса, то компилятор ищет сначала в пределах класса, включая все его базовые классы. 4 Если у класса есть функции-члены operator new() и operator delete(), эти функции и используются в выражении new или delete. 4 В противном случае компилятор ищет соответствующую функцию в глобальной области видимости. 4
- Использовать функции malloc() и free(). 4 Они определяются в заголовке cstdlib и позволяют резервировать и освобождать память. 4 Функция malloc() получает параметр типа size_t, задающий количество резервируемых байтов. 4 Она возвращает указатель на зарезервированную область памяти или значение 0, если зарезервировать память не удалось. 4 Функция free() получает параметр типа void*, являющийся копией указателя, возвращённого функцией malloc(), и возвращает занятую память операционной системе. 4
Пример простейшего кода функций operator new() и operator delete(): 4
void *operator new(size_t size) { if (void *mem = malloc(size)) return mem; else throw bad_alloc();}void operator delete(void *mem) noexcept { free(mem);}
Такие пользовательские функции должны соблюдать семантику встроенных (не выделять уже выделенные адреса и т. п.). 5