У меня есть массив значений, который передается моей функции из другой части программы, которую мне нужно сохранить для последующей обработки. Так как я не знаю, сколько раз будет вызываться моя функция, прежде чем придет время обрабатывать данные, мне нужна динамическая структура хранения, поэтому я выбрал файл std::vector
. Я не хочу делать стандартный цикл для push_back
всех значений по отдельности, было бы неплохо, если бы я мог просто скопировать все это, используя что-то похожее на memcpy
.
vec.assign(a, a+n)
, что будет более компактным, чем копирование и изменение размера.Здесь было много ответов, и почти все из них выполнят свою работу.
Однако есть несколько вводящих в заблуждение советов!
Вот варианты:
Короче говоря, метод 4 с использованием vector :: insert является лучшим для сценария bsruth.
Вот некоторые кровавые подробности:
Метод 1 , вероятно, самый простой для понимания. Просто скопируйте каждый элемент из массива и вставьте его в конец вектора. Увы, медленно. Поскольку существует цикл (подразумеваемый функцией копирования), каждый элемент должен обрабатываться индивидуально; Никакого улучшения производительности нельзя сделать на основании того факта, что мы знаем, что массив и векторы являются смежными блоками.
Метод 2 - это предлагаемое улучшение производительности метода 1; просто зарезервируйте размер массива перед его добавлением. Для больших массивов это может помочь. Однако лучший совет здесь - никогда не использовать резерв, если профилирование не предполагает, что вы можете получить улучшение (или вам нужно убедиться, что ваши итераторы не будут аннулированы). Бьярн соглашается . Кстати, я обнаружил , что этот метод выполняется медленнее большую часть времени , хотя я изо всех сил , чтобы всесторонне объяснить , почему это было регулярно значительно медленнее , чем метод 1 ...
Метод 3 - это старомодное решение - добавьте немного C в проблему! Отлично и быстро работает для типов POD. В этом случае необходимо вызвать изменение размера, поскольку memcpy работает за пределами вектора, и нет способа сообщить вектору, что его размер изменился. Помимо того, что это уродливое решение (байтовое копирование!), Помните, что это можно использовать только для типов POD . Я бы никогда не использовал это решение.
Метод 4 - лучший способ. Его смысл ясен, он (обычно) самый быстрый и работает для любых объектов. У использования этого метода для этого приложения нет недостатков.
Метод 5 - это настройка метода 4 - скопируйте массив в вектор, а затем добавьте его. Хороший вариант - в целом шустрый и понятный.
Наконец, вы знаете, что вы можете использовать векторы вместо массивов, верно? Даже если функция ожидает массивы в стиле c, вы можете использовать векторы:
Надеюсь, это поможет кому-то там!
источник
&expr
не оцениваетexpr
, а только вычисляет его адрес. И указатель один за последний элемент вполне допустимо, тоже.dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
- мне кажется намного понятнее. Ничего не может получить от метода 5, только выглядит довольно неэффективным - если компилятор не сможет снова оптимизировать вектор.Если все, что вы делаете, это заменяете существующие данные, вы можете сделать это
источник
std :: copy - это то, что вы ищете.
источник
Поскольку я могу редактировать только свой ответ, я собираюсь составить ответ на основе других ответов на свой вопрос. Спасибо всем, кто ответил.
Использование std :: copy по- прежнему выполняет итерацию в фоновом режиме, но вам не нужно вводить код.
Используя обычный memcpy . Вероятно, это лучше всего использовать для основных типов данных (например, int), но не для более сложных массивов структур или классов.
источник
- избегай memcpy, - говорю я. Нет причин возиться с операциями с указателями, если только в этом нет необходимости. Кроме того, он будет работать только для типов POD (например, int), но не сработает, если вы имеете дело с типами, требующими построения.
источник
источник
myints
?Еще один ответ, поскольку человек сказал: «Я не знаю, сколько раз будет вызываться моя функция», вы можете использовать метод вставки вектора, например, для добавления массивов значений в конец вектора:
Мне нравится этот способ, потому что реализация вектора должна иметь возможность оптимизировать для наилучшего способа вставки значений на основе типа итератора и самого типа. Вы несколько отвечаете на реализацию stl.
Если вам нужно гарантировать максимальную скорость и вы знаете, что ваш тип является типом POD, я бы порекомендовал метод изменения размера в ответе Томаса:
источник
В дополнение к методам, представленным выше, вам необходимо убедиться, что вы используете либо std :: Vector.reserve (), std :: Vector.resize (), либо сконструируете вектор по размеру, чтобы убедиться, что ваш вектор имеет достаточно элементов в это для хранения ваших данных. в противном случае вы испортите память. Это верно как для std :: copy (), так и для memcpy ().
Это причина использования vector.push_back (), вы не можете писать за концом вектора.
источник
Предположим, вы знаете, насколько велик элемент в векторе:
http://www.cppreference.com/wiki/stl/vector/start
источник