Jump to content

создать и удалить (C++)

(Перенаправлено с нового оператора )


На ++ языке программирования C новый и delete — это пара языковых конструкций , которые выполняют динамическое выделение памяти , создание и уничтожение объектов . [1]

За исключением формы, называемой «новое размещение» , Оператор new процесса обозначает запрос на выделение памяти в куче . Если доступно достаточно памяти, new инициализирует память, вызывая при необходимости конструкторы объектов, и возвращает адрес вновь выделенной и инициализированной памяти. [2] [3] А новый запрос в простейшей форме выглядит следующим образом:

p = new T;

где p — ранее объявленный указатель типа T (или какой-либо другой тип, к которому Может быть назначен указатель T , например суперкласс , Т ). Конструктор по умолчанию для T , если таковой имеется, вызывается для построения Экземпляр T в выделенном буфере памяти.

Если в свободном хранилище недостаточно памяти для объекта типа Т , новый запрос указывает на сбой, выдавая исключение типа std::bad_alloc . Это устраняет необходимость явно проверять результат выделения.

Аналог освобождения новое это delete , который сначала вызывает деструктор (если есть) для своего аргумента, а затем возвращает память, выделенную новый вернулся в бесплатный магазин. Каждый звонок в new должен соответствовать вызову удалить ; невыполнение этого требования приводит к утечке памяти . [1]

новый синтаксис имеет несколько вариантов, которые позволяют более точно контролировать выделение памяти и создание объектов. Синтаксис, подобный вызову функции, используется для вызова конструктора, отличного от конструктора по умолчанию, и передачи ему аргументов, например:

p = new T(argument);

вызывает одинаргумент Конструктор T вместо конструктора по умолчанию при инициализации вновь выделенного буфера.

Другой вариант выделяет и инициализирует массивы объектов, а не отдельные объекты:

p = new T [N];

При этом из свободного хранилища запрашивается буфер памяти, достаточно большой для хранения непрерывного массива N объектов типа T и вызывает конструктор по умолчанию для каждого элемента массива.

Память, выделенная с помощью new[] должен быть освобожден с помощью оператор delete[] , а не удалить . Использование неподходящей формы приводит к неопределенному поведению . Компиляторы C++ не обязаны генерировать диагностическое сообщение при использовании неправильной формы.

Стандарт C++11 определяет дополнительный синтаксис:

p = new T[N] {initializer1, ..., initializerN};

который инициализирует каждый п[ я ] к инициализатор i+1 .

Обработка ошибок

[ редактировать ]

Если new не может найти достаточно памяти для обслуживания запроса на выделение, он может сообщить об ошибке тремя различными способами. Во-первых, стандарт ISO C++ позволяет программам регистрировать пользовательскую функцию, называемую new_handler C++ со средой выполнения ; если да, то эта функция вызывается всякий раз, когда новый сталкивается с ошибкой. new_handler может попытаться освободить больше памяти или завершить программу, если это невозможно.

Если нет new_handler установлен, вместо этого new выдает исключение типа std::bad_alloc . Таким образом, программе не нужно проверять значение возвращаемого указателя, как это принято в C ; если исключение не было создано, выделение выполнено успешно.

Третий метод обработки ошибок представлен вариантной формой new(std::nothrow) , который указывает, что исключение не должно создаваться; вместо этого нулевой указатель возвращается , сигнализирующий об ошибке выделения.

Перегрузка

[ редактировать ]

The Оператор new можно перегрузить , чтобы определенные типы (классы) использовали для своих экземпляров собственные алгоритмы выделения памяти. Например, ниже приведен вариант шаблона Singleton , где первый новый вызов Singleton выделяет экземпляр, и все последующие вызовы возвращают тот же экземпляр:

#include <cstdlib>
#include <cstddef>

class Singleton {
public:
  static void* operator new(std::size_t size) {
    if (!instance) {
      instance = std::malloc(size);
    }
    refcount++;
    return instance;
  }

  static void operator delete(void*) noexcept {
    if (--refcount == 0) {
      std::free(instance);
      instance = nullptr;
    }
  }

private:
  static void* instance = nullptr;
  static std::size_t refcount = 0;
};

Эта возможность была доступна с самого начала истории C++, хотя конкретный механизм перегрузки изменился. Он был добавлен в язык, потому что объектно-ориентированные программы C++ имели тенденцию размещать множество небольших объектов с new , который внутри использовал распределитель C (см. § Связь с malloc и free ); однако это было оптимизировано для меньшего и большего количества выделений, выполняемых типичными программами на языке C. Страуструп сообщил, что в ранних приложениях функция C malloc был «наиболее распространенным узким местом производительности в реальных системах», поскольку программы тратили на эту функцию до 50% своего времени. [4]

Отношение к malloc и бесплатному

[ редактировать ]

Поскольку стандарт C++ включает в себя стандартную библиотеку C , динамического выделения памяти C процедуры маллок , каллок , перераспределить и бесплатно также доступны программистам на C++. Использование этих подпрограмм в большинстве случаев не рекомендуется, поскольку они не выполняют инициализацию и уничтожение объектов. [5] новый и delete были фактически введены в первую версию C++ (тогда называвшуюся « C с классами »), чтобы избежать необходимости инициализации объектов вручную. [4]

В отличие от процедур C, которые позволяют увеличивать или уменьшать выделенный массив с помощью realloc невозможно изменить размер буфера памяти, выделенного новый[] . Вместо этого стандартная библиотека C ++ предоставляет динамический массив (коллекцию), который можно расширять или уменьшать по своему усмотрению. std::vector класс шаблона .

Стандарт C++ не определяет никакой связи между новый / delete и процедуры распределения памяти C, но новый и delete обычно реализуются как обертки вокруг маллок и бесплатно . [6] Смешивание двух семейств операций, например, освобождение новая выделенная память или удалить malloc'd памяти вызывает неопределенное поведение и на практике может привести к различным катастрофическим результатам, таким как неспособность снять блокировки и, следовательно, взаимоблокировка . [7]

См. также

[ редактировать ]
  1. ^ Jump up to: а б Савич, Уолтер (2013). Абсолютный С++ . Пирсон. стр. 420–445. ISBN  978-0132846813 .
  2. ^ «Документация IBM, описывающая новый оператор C++» . Архивировано из оригинала 3 января 2013 г. Проверено 6 ноября 2013 г.
  3. ^ «Новая документация по оператору Microsoft Visual Studio» . Проверено 6 ноября 2013 г.
  4. ^ Jump up to: а б Страуструп, Бьярн (1993). История C++: 1979–1991 (PDF) . Учеб. Конференция ACM по истории языков программирования.
  5. ^ Мейерс, Скотт (1998). Эффективный С++ . Аддисон-Уэсли. п. 21 . ISBN  9780201924886 .
  6. ^ Александреску, Андрей (2001). Современный дизайн на C++: применение общих шаблонов программирования и проектирования . Аддисон-Уэсли. п. 68 .
  7. ^ Сикорд, Роберт К. (2013). Безопасное программирование на C и C++ . Аддисон-Уэсли. Раздел 4.4, Распространенные ошибки управления памятью C++.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 1b0e1e5f6020c270b977006d4eec8e3a__1718636220
URL1:https://arc.ask3.ru/arc/aa/1b/3a/1b0e1e5f6020c270b977006d4eec8e3a.html
Заголовок, (Title) документа по адресу, URL1:
new and delete (C++) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)