Что делает новый оператор C++, кроме выделения и вызова ctor?

StackOverflow https://stackoverflow.com/questions/377178

  •  22-08-2019
  •  | 
  •  

Вопрос

Какие еще вещи new Оператор делает что-то кроме выделения памяти и вызова конструктора?

Это было полезно?

Решение

В стандарте C++ это говорится о форме одного объекта (обычно используемой форме) нового оператора из <new> заголовок:

Требуемое поведение:

Верните указатель ненауллов на соответствующим образом выровненное хранилище (3.7.3), или иначе бросьте исключение BAD_ALLOC.Это требование является обязательным для заменяющей версии этой функции.

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

— Выполняет цикл:Внутри цикла функция сначала пытается выделить запрошенную память.Заключает ли попытка призыв к стандартной библиотечной функции C, Malloc не определен.

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

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

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

В стандарте есть много чего сказано о новом операторе и динамическом распределении памяти (очень много можно сказать), но я думаю, что список «Поведение по умолчанию» довольно хорошо суммирует основы нового оператора.

Другие советы

Я написал объяснение того, что он делает в этот отвечать.Это объясняет, как

  • new получает память
  • new обрабатывает сбой памяти
  • new обрабатывает исключения конструктора
  • new обрабатывает специальные версии и версии с откидным расположением

Майкл объяснил, как функция распределения по умолчанию (::operator new) хорошо распределяет память и как она обрабатывает сбои.Я видел ваш вопрос о том, где хранится размер объекта в его комментариях.Ответ: размер не сохраняется, если это не необходимо.Помните, что C не нужен размер для free (и ::operator new можно просто использовать malloc):

void * memory = malloc(x);
free (memory); // no need to tell it the size

Вот пример, в котором вы видите, как сохранение размера влияет на размер выделения для формы массива нового выражения (не описано в другом моем ответе):

#include <cstddef>
#include <iostream>

struct f {
    // requests allocation of t bytes
    void * operator new[](std::size_t t) throw() {
        void *p = ::operator new[](t);
        std::cout << "new    p: " << p << std::endl;
        std::cout << "new size: " << t << std::endl;
        return p;
    }

    // requests deleting of t bytes starting at p
    void operator delete[](void *p, std::size_t t) throw() {
        std::cout << "delete p: " << p << std::endl;
        std::cout << "size    : " << t << std::endl;
        return ::operator delete[](p);
    }
};

int main() {
    std::cout << "sizeof f: " << sizeof (f) << std::endl;

    f * f_ = new f[1];
    std::cout << "&f_     : " << f_ << std::endl;
    delete[] f_;
}

Он напечатает что-то вроде этого:

sizeof f: 1
new    p: 0x93fe008
new size: 5
&f_     : 0x93fe00c
delete p: 0x93fe008
size    : 5

Один байт для самого объекта и 4 байта для счетчика, который хранится непосредственно перед выделенной областью объекта.Теперь, если мы используем функцию освобождения без параметра размера (просто удалив его из оператора delete), мы получим следующий результат:

sizeof f: 1
new    p: 0x9451008
new size: 1
&f_     : 0x9451008
delete p: 0x9451008

Среда выполнения C++ здесь не заботится о размере, поэтому она больше не сохраняет его.Обратите внимание, что это сильно зависит от реализации, и именно это здесь делает gcc, чтобы сообщить вам размер в операторе-члене delete.Другие реализации могут по-прежнему сохранять размер, и, скорее всего, так и будет, если для класса можно вызвать деструктор.Например, просто добавив ~f() { } выше заставляет gcc сохранять размер независимо от того, какую функцию освобождения мы пишем.

Зависит от того, перегружено оно или нет, создали ли вы приложение для отладки, используете ли вы детектор утечек памяти, есть ли у вас какая-то схема объединения памяти, есть ли у вас что-то вроде сборщика мусора Boehm, который помечает/снимает маркировку битов и т. д. и т. д.Внутри может быть много нестандартных вещей или вообще ничего особенного.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top