Как я могу назвать оригинальный «оператор новый», если я его перегрузил? - PullRequest
28 голосов
/ 09 ноября 2010

Предположим, мне нужно перегрузить глобальные ::operator new() для хранения дополнительных данных с каждым выделенным объектом .Таким образом, в основном это будет работать следующим образом:

  • для каждого вызова global ::operator new() будет принимать переданный размер объекта и добавлять размер дополнительных данных
  • будет выделить блок памяти размера, выведенного на предыдущем шаге
  • , он сместит указатель на ту часть блока, которая не занята дополнительными данными, и вернет это значение смещения вызывающей стороне

::operator delete() сделает то же самое в обратном порядке - сместит указатель, получит доступ к дополнительным данным, освободит память.

Теперь вопрос как мне выделить память ?Конечно, я могу вызвать malloc() или какую-нибудь платформо-зависимую функцию (как обычно это делается).Но обычно, когда мне нужно выделить необработанную память в C ++, я вызываю ::operator new().Могу ли я позвонить оригинальному ::operator new(), чтобы выполнить выделение памяти изнутри моего перегруженного глобального ::operator new()?

1 Ответ

19 голосов
/ 09 ноября 2010

Вы не можете получить к ним доступ, потому что на самом деле это не перегрузка, это замена.Когда вы определяете свой ::operator new, старый исчезает.Это в значительной степени так.

По сути, вам нужно позвонить malloc с пользовательского ::operator new.Мало того, но также следуйте указаниям в 18.4.1.1/4 для правильной обработки ошибок:

Поведение по умолчанию:

- Выполняет цикл: внутри цикла сначала выполняется функцияпытается выделить запрошенное хранилище.Влечет ли попытка вызова функции библиотеки Standard C malloc, не уточняется.

- возвращает указатель на выделенное хранилище, если попытка была успешной.В противном случае, если последний аргумент для set_new_handler () был нулевым указателем, выведите bad_alloc.

- В противном случае функция вызывает текущий new_handler (18.4.2.2).Если вызванная функция возвращается, цикл повторяется.

- Цикл завершается, когда попытка выделить запрошенное хранилище успешна или когда вызываемая функция new_handler не возвращает.

...