Как станд. C++:: вектор реализован?

Я использовал std::vector много, и недавно я задал мне этот вопрос: "Как std::vector реализованный?"

У меня было две альтернативы:

1) Связанный список и затем то, чтобы заставлять API чувствовать себя подобно произвольному доступу (т.е. перегрузка operator[]).

2) Используя new, например. Foo* temp = new Foo[20]: Я полагаю, что они делают что-то вроде этого, но затем это поднимает еще один вопрос. Они всегда выделяют максимум (uint32_t) устройство хранения данных для предоставления произвольного доступа? (Это неэффективно с точки зрения памяти.)

Или есть ли что-то еще, о чем я должен знать?

39
задан Padma Kumar 26 November 2012 в 13:34
поделиться

9 ответов

С помощью svgweb можно встроить произвольный кросс-браузер SVG и изменить его обычными методами DOM. Сюда входит присоединение прослушивателей событий к любой части SVG.

svgweb главная страница:
http://code.google.com/p/svgweb/

svgweb quickstart (также обсуждается добавление прослушивателей событий):
http://codinginparadise.org/projects/svgweb/docs/QuickStart.html

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

-121--3140653-

Я думаю, что в этой идее есть некоторые достоинства. Уже есть приложения, которые измеряют скорость ветра с помощью микрофона iPhone, и они, видимо, довольно точны.

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

В будущем выпуске вы можете измерить скорость и ускорение, с которыми другие пользователи iPhone отходят от события, чтобы определить эффективный радиус и силу взрыва.

Изменить:

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

> The code uses: the AU Remote IO audio
> unit to get the audio input and copy
> it to the output the UI presents:
> - Oscilloscope view of the audio
> - time domain
> - frequency domain
> - Scrolling sonogram of the audio

Есть некоторые дополнительные сведения о StackOverflow, связанные с тем, чтобы получить эту работу здесь:

aurioTouch Образец приложения аудио воспроизведение/через не работает? AurioTouch & FFT для тюнера приборов

Удачи, и может ветер быть у вас сзади!

-121--1067439-

Он реализован с использованием базового массива.

Невозможно реализовать std:: vector < T > со связанным списком, поскольку стандарт гарантирует, что элементы списка будут храниться в непрерывной памяти.

43
ответ дан 27 November 2019 в 02:20
поделиться

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

Затем вектор использует в разделе «Распределение», чтобы вызвать конструкторов класса в правильном месте после того, как каждый слот на самом деле используется фактически используемый.

Когда есть расширение, он попытается перераспределить на месте (но это немного глупо и нормально не работает, думают, что уплотнение кучи Windows 98), но обычно в конечном итоге в конечном итоге будет создавать совершенно новое распределение и копирование.

Стандартный вектор STL всегда все вместе, но не все реализации работают так (я знаю, написав некоторые из них). Вероятно, никто не имел бы не именно связанный список.

1
ответ дан 27 November 2019 в 02:20
поделиться

Педагогическая (и, таким образом упрощенная) версия контейнера под названием «VEC» обсуждается в главе 11 замечательной (вводной) книги «Ускоренного C ++». То, что они описывают, это улавшаяся версия STD :: Vector, но я думаю, что все еще стоит отметить, что:

1) они реализуют свой класс шаблона с точки зрения массива,

2) обсуждают Push_back в Условия трюка (упомянутые выше) выделения большего количества хранения, чем требуются и возвращаются к большему количеству при запуске, а

3) они используют распределитель > для управления памятью. Новый оператор не достаточно гибкий в этом контексте, поскольку он оба выделяет и инициализирует память.

Я повторяю, хотя это не означает, что фактические реализации существуют это просто. Но поскольку «ускоренные C ++» довольно широко распространены, тех, кто заинтересован может найти в соответствующей главе одностороннее, что векторные объекты могут быть созданы, скопированы, назначены и уничтожены.

Отредактируйте: в соответствующем примечании я только что нашел следующее сообщение в блоге травой Satter, в котором он комментирует более раннее сообщение в блоге Эндрю Кениг, относительно того, следует ли беспокоиться о векторных элементах, которые являются смежными в памяти: Крыть не: векторы гарантированно могут быть смежными .

2
ответ дан 27 November 2019 в 02:20
поделиться

Раздел 23.2.4, ¶1 стандарта требует, чтобы арифметика по указателям в вектор работать так же, как и с указателями в массив.

Элементы вектора хранятся непрерывно, что означает, что если V это Вектор, где т это некоторые Тип, кроме BoOL, то он подчиняется Идентичность и V [N] == & V [0] + N для Все 0 <= n

Это гарантирует, что хранение находится в массиве. Конечно, если вы измените размер массива, чтобы быть больше, это может быть перемещено в память.

2
ответ дан 27 November 2019 в 02:20
поделиться

Я считаю, что STL использует опцию № 2 (или что-то подобное), потому что STD :: Vector <> гарантированно хранит элементы в смежной памяти.

Если вы ищете структуру памяти, которая не должна использовать непрерывную память, посмотрите на STD :: DECE.

1
ответ дан 27 November 2019 в 02:20
поделиться

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

Кстати, один общий способ экологизации массива - это удвоить размер по мере необходимости. Это так, чтобы если вы вставляете N элементов o (log n) o (log n) , выполняются и не более o (n) пространство впустую.

Вы можете прочитать одну реализацию для себя в SGI (где был первоначально задуман STL).

16
ответ дан 27 November 2019 в 02:20
поделиться

Нет ни одного способа его реализации. Различные реализации могут быть разными, при условии сохранения семантики и соответствия требованиям.

В любой момент времени должен существовать примитивный массив Т, удовлетворяющий требованиям непрерывности. Однако, как он распределяется, растет, уменьшается и освобождается, зависит от реализации.

Реализацию можно прочитать самостоятельно, она находится прямо там, в заголовочном файле.

Могу сказать, что no реализации используют связанные списки. Они не соответствуют требованиям стандарта.

2
ответ дан 27 November 2019 в 02:20
поделиться

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

1) Элементы векторов могут быть смежными, поддерживающими O (1) Случайный доступ и векторы должны быть совместимы с помощью Crays C. Это просто подразумевает, что нет связанных списков.

2) Когда вы называете резерв, он резервирует дополнительную память. Но резерв называет

new T[newSize]

, чтобы зарезервировать больше памяти. В противном случае он будет звонить конструктору по умолчанию. Как объяснил uncleben всякий раз, когда Reserve называется вектором класса, просто выделяет более неинициализированную память USIN его распределитель (если требуется) и скопируйте создание новых объектов в эту память, используя размещение New (если выделено больше памяти)

3) Изначально вектор имеет некоторые емкость по умолчанию. Для чего выделяется неинициализированная память, когда конструкция векторного объекта

4) Push_Back Copy Создает объект в первое доступное местоположение. При необходимости больше памяти необходимо выделить аналогичным образом как резерв

0
ответ дан 27 November 2019 в 02:20
поделиться

Я считаю, что это третий вариант. Он не может просто использовать new T [n] , потому что тогда ему фактически придется создавать столько объектов, сколько он выделяет. Например,

std::vector<Foo> v;
v.reserve(10);

Если ваша реализация просто завершила выполнение new Foo [10] , то вы бы просто построили 10 экземпляров Foo.

Вместо этого он использует свой распределитель для выделения и освобождения необработанной памяти (без создания объектов) и по мере необходимости (например, когда вы на самом деле push_back объекты) помещает созданные копии экземпляры в правильные места в своей памяти. зарезервировать, используя размещение new , и удаляет их с помощью явных вызовов деструктора (что вы можете делать только в сочетании с размещением new). Класс распределителя предоставляет следующие методы для того, что, как я полагаю, использует реализации векторов

 void construct(pointer p, const_reference val);

  Returns:
    new((void *)p) T(val)

  void destroy(pointer p);

  Returns:
    ((T*)p)->~T()

(«Возвращает», вероятно, следует читать «эффект» или что-то подобное.)

Подробнее о размещении new

24
ответ дан 27 November 2019 в 02:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: