Дизайн внутренней функции _S_oom_malloc в SGI-STL-распределителе
Код выглядит следующим образом:
template <int __inst>
void*
__malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)
{
void (* __my_malloc_handler)();
void* __result;
for (;;) {
__my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == __my_malloc_handler) { __THROW_BAD_ALLOC; }
(*__my_malloc_handler)();
__result = malloc(__n);
if (__result) return(__result);
}
}
У меня два вопроса. 1. почему _S_oom_malloc использует бесконечный цикл? 2. как мы знаем, _S_oom_malloc будет вызываться при сбое malloc в функции __malloc_alloc_template::allocate. И почему он использует malloc для выделения пространства?
Кто-нибудь может мне помочь? Большое спасибо.
1 ответ
Во-первых, цикл не является действительно бесконечным. Есть два выхода: бросая BAD_ALLOC
исключение путем выделения запрошенного объема памяти. Исключение будет выдано, когда текущий новый обработчик является нулевым указателем.
Чтобы понять, как это может произойти, обратитесь, например, к пункту 49 из Effective C++. По сути, любой новый обработчик может
- Сделайте больше памяти доступным
- Установите другой новый обработчик
- Деинсталлируйте новый обработчик (то есть передав нулевой указатель на
set_new_handler
- Бросить исключение
abort
или жеexit
Во-вторых, причина того, что он использует библиотеку C malloc
выделить место в том, что malloc
на большинстве систем это хорошо проверенная и эффективно реализованная функция. Стандартная библиотека new
функции - это просто "безопасные" исключения и типобезопасные обертки вокруг него (которые вы, как пользователь, также можете переопределить, если хотите).