Размещение размещения контейнеров STL новый - PullRequest
5 голосов
/ 14 марта 2011

Я не мог найти точный ответ на этот вопрос и, следовательно, размещать здесь.Когда я думаю о векторе, он должен строить объекты в смежной области памяти.Это означает, что вектор сохраняет выделенную память и должен выполнить конструкцию на месте (= размещение нового) объектов, помещаемых в нее.Это правильное предположение?Кроме того, означает ли это, что контейнер вручную вызывает деструктор, а не вызывает удаление?Есть ли другие предположения, которые я здесь пропускаю?Означает ли это, что я могу предположить, что даже пользовательский текст, написанный новым для объекта, не может быть вызван, если я выбрал запись?

Также имеет смысл использовать список для нового и удаления, поскольку нам не нужногарантия непрерывной памяти.Итак, является ли этот тип поведения тем, что управляет поведением распределителей?Пожалуйста помоги.Спасибо

Ответы [ 2 ]

4 голосов
/ 15 марта 2011

Это означает, что вектор сохраняет выделенную память и должен выполнить конструкцию на месте (= размещение нового) объектов, помещаемых в нее. Это правильное предположение?

Да

Кроме того, означает ли это, что контейнер вручную вызывает деструктор, а не вызывает удаление?

Да

Есть ли другие предположения, которые я здесь упускаю? Означает ли это, что я могу предположить, что даже пользовательский текст, написанный новым для объекта, не может быть вызван, если я выбрал запись?

Да. Учтите, что даже в связанных списках контейнер не будет выделять экземпляр вашего типа, а скорее является шаблонной структурой, которая содержит подобъект типа. Для связанного списка это будет некоторый сложный тип, содержащий как минимум два указателя (обе ссылки) и подобъект вашего типа. Фактический тип, который выделен, - это узел , а не ваш тип.

Также имеет смысл использовать список для нового и удаления, поскольку нам не требуется гарантия непрерывной памяти.

Да, но не new / delete объектов вашего типа.

Итак, такое поведение ведет к тому, как ведут себя распределители?

Я действительно не понимаю эту часть вопроса. Распределители - это классы, которые имеют набор ограничений, определенных в стандарте, которые включают как интерфейс (allocate, deallocate ...), так и семантику (значение == состоит в том, что память, выделенная одним, может быть освобождена другое, любое другое состояние в классе не имеет значения).

Распределители могут создаваться и передаваться в контейнеры по разным причинам, включая эффективность (если вы выделяете только тип объекта, то вы можете реализовать небольшие распределители блоков чуть более эффективно, чем malloc - или нет, зависит от ситуации).

Примечание по размещению новых

Мне всегда было интересно, что размещение новых - это термин, который, по-видимому, имеет два отдельных значения. С одной стороны - единственный способ построить объект на месте . Но, похоже, это также имеет совершенно другое значение: создайте этот объект, получая память из пользовательского распределителя .

На самом деле существует одно значение размещения нового , которое не имеет ничего общего с созданием на месте . Первый - это случай второго, где распределитель предоставляется реализацией (компилятором), как определено в 18.4.1.3, и не может быть перегружен. Эта конкретная версия перегруженного распределителя ничего не делает, кроме как возвращает аргумент (void*), чтобы new-expression могло передать его в конструктор и создать объект в памяти (не), выделенной размещение новой версии, которая была вызвана.

3 голосов
/ 14 марта 2011

Ты очень близок к тому, чтобы быть совершенно правильным. Способ, которым vector (и все другие стандартные контейнеры) выполняют свое размещение, заключается в использовании класса std::allocator, который поддерживает построение и разрушение объектов в определенных местах. Внутренне это использует размещение новых и явных вызовов деструкторов для установки и уничтожения объектов.

Причина, по которой я говорю «очень близко к идеальности», заключается в том, что можно настроить способ, которым контейнеры STL получают свою память, предоставив новый распределитель в качестве аргумента шаблона вместо значения по умолчанию. Это означает, что в теории должна быть возможность создавать и уничтожать контейнеры STL различными способами, хотя по умолчанию они будут использовать стандартное размещение new.

...