C ++: безопасно ли работать с std :: vectors, как если бы они были массивами? - PullRequest
10 голосов
/ 24 декабря 2010

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

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

  • , чтобы получить индекс элемента в этом массиве, я бы предпочел избегать наличия поля index внутри моегоэлементы, но лучше играть с арифметикой указателей (то есть: индекс Element *x будет x - & array[0]) - кстати, это звучит грязно для меня: это хорошая практика или я должен сделать что-то еще?


Безопасно ли использовать std::vector для этого?

Что-то заставляет меня думать, что std::array будет более подходящим, но:

  • Конструктор и деструктор для моей структуры будут называться редко: я не возражаю против таких накладных расходов.

  • Я собираюсь установить емкость std::vector в нужном мне размере(размер, который будет использоваться для std::array, таким образом, не потребует никаких накладных расходов из-за спорадического перераспределения.

  • Я не возражаю против небольших накладных расходов на std::vector 's внутренняя структура.

  • Я мог бы использовать возможность изменить размер вектора (или лучше: чтобы иметьразмер выбирается во время установки), и я думаю, что нет способа сделать это с помощью std :: array, так как его размер является параметром шаблона (это очень плохо: я мог бы сделать это даже со старым C-подобным массивом, просто динамически выделяя его)это в куче).


Если std::vector подходит для моих целей, я хотел бы узнать подробности, будут ли какие-то накладные расходы во время выполнения относительно std::array (или к простому массиву C):

Я знаю, что он вызовет конструктор по умолчанию для любого элемента, как только я увеличу его размер (но я думаю, это ничего не будет стоить, если мои данные получатпустой конструктор по умолчанию?), то же самое для деструктора.Что-нибудь еще?

Ответы [ 6 ]

5 голосов
/ 24 декабря 2010

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

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

2 голосов
/ 24 декабря 2010

Хорошо обрабатывать данные в std :: vector как массив, получить указатель на начало с помощью & v [0].Очевидно, что если вы сделаете что-либо, что может перераспределить данные, то ваши указатели, вероятно, будут признаны недействительными.

0 голосов
/ 24 декабря 2010

Работа в многопоточной среде и динамическое выделение памяти могут вызвать проблемы, потому что vector обычно представляет собой непрерывный кусок памяти, а указатели могут не быть!

0 голосов
/ 24 декабря 2010

Если вам действительно нужен массив std ::, вы можете использовать boost :: array.Это похоже на обычный массив, но поддерживает итераторы, и вы можете легко использовать его с алгоритмами STL.

0 голосов
/ 24 декабря 2010

Это даже безопаснее, чем массив в стеке: насколько велик ваш стек? насколько большим может стать ваш массив (фиксированный размер, но размер может быть увеличен в более поздних версиях)?

0 голосов
/ 24 декабря 2010

Да, вы можете использовать его как массив в OpenGL :) Пример:

glBufferData( GL_ARRAY_BUFFER_ARB, dataVec.size() * sizeof( dataVec[0] ), &dataVec[0], GL_STATIC_DRAW_ARB );

Где dataVec является стандартным: :: Vector

...