Дизайн внутренней функции _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 функции - это просто "безопасные" исключения и типобезопасные обертки вокруг него (которые вы, как пользователь, также можете переопределить, если хотите).

Другие вопросы по тегам