Correct way to set the size of a std::vector
From what I read, std::vector is the appropriate structure to use when interfacing with c function requiring a contiguous memory byte array. However I was wondering how I can determine the size of the array in some cases
I have written a small sample program to illustrate what I mean.
The output is (not much surprising):
The reason why I did this is, because I reserve a buffer of a certain size and then pass this memory to a socket via recv() . Since I have to pass the memory as a pointer, there is no way that the vector size gets adjusted according to what recv returns. Now when the received number of bytes is smaller then the buffer, I would have thought that I can somehow adjust the size of the vector, so when I pass it back, the caller can do v.size() and the the number of elements aka returned by receive.
When I looked at the data from the above example, when using resize() the size of the buffer is adjusted correctly, but the data is gone. So do I really have to copy the memory individually into a new vector just to get the correct size? This sounds like a really unnecessary overhead to me. Or is there some way to tell the vector how many elements it currently is supposed to hold?
Как увеличить размер вектора c
Vectors are known as dynamic arrays which can change its size automatically when an element is inserted or deleted. This storage is maintained by container.
The function alters the container’s content in actual by inserting or deleting the elements from it. It happens so,
- If the given value of n is less than the size at present then extra elements are demolished.
- If n is more than current size of container then upcoming elements are appended at the end of the vector.
Syntax:
Below programs illustrate the working of the function
1.Size of the vector container is lowered.
2. Size of the vector container is increased.
3.Size of the vector container is increased and new elements are initialized with specified value.
Класс vector . Методы, определяющие и изменяющие общие характеристики массива
Метод max_size() позволяет получить максимально-допустимое количество элементов массива. Это значение зависит от типа элементов массива vector. Для различных типов оно разное
В зависимости от типа данных массива vector , это значение может колебаться. Чем больше размер данных каждого элемента массива vector , тем меньше значение max_size() .
Синтаксис объявления метода max_size() следующий:
здесь T – тип элементов динамического массива.
Пример.
3. Метод capacity() . Определить размер массива с учетом зарезервированной памяти
Метод capacity() возвращает количество элементов, выделенное для массива.
При добавлении нового элемента в массив, нужно выделить дополнительную память на 1 элемент больше. Однако, компилятор может увеличить размер памяти на несколько элементов чтобы при последующем добавлении еще одного элемента не выполнять повторно такие операции как освобождение памяти под предварительно созданный массив, выделение нового фрагмента и тому подобное. Таким образом ускоряется быстродействие.
Синтаксис объявления метода следующий
здесь T – тип элементов массива.
Пример. В примере демонстрируется разница между методами size() и capacity() .
Результат выполнения программы
Как видно из результата, при добавлении нового элемента, количество элементов в массиве увеличилась на 1 и составляет 11 (метод size() ). Однако, сам размер массива увеличился на 5 элементов и составляет 15 (метод capacity() ). Теперь можно добавлять еще 4 элемента без лишнего перераспределения памяти. Если добавление элементов будет выполняться в цикле, то такой подход позволит ускорить выполнение программы.
4. Метод empty() . Определить, пустой ли вектор
С помощью метода empty() можно определить, пустой ли массив (количество элементов в массиве равно 0). Общая форма метода empty() следующая:
здесь T – тип элементов массива.
Пример.
Результат выполнения программы
5. Метод shrink_to_fit() . Установить размер массива в памяти по количеству элементов в нем без дополнительного резервирования памяти
Метод shrink_to_fit() позволяет выровнять память, выделенную (зарезервированную) для элементов массива (метод c apacity() ) с памятью, занятой элементами массива (метод size() ).
Количество зарезервированных элементов (для которых выделена память) возвращается методом capacity() . Количество элементов, определенных в массиве, возвращаются методом size() . Значение, возвращаемое методом capacity() всегда больше или равно значения, возвращаемого методом size() .
Если значение, полученное методом capacity() больше значения, полученного методом size() , то метод shrink_to_fit() позволяет выровнять эти значения. При этом уменьшается размер памяти, возвращаемый методом capacity() .
Метод эффективен, когда в результате различных операций с массивом, остается большой избыток зарезервированных элементов в массиве.
Общая форма метода следующая
После вызова этого метода, методы size() и capacity() всегда будут возвращать одинаковые значения.
Пример.
Результат выполнения программы
Как видно из результата, после добавления элемента в массив, размер массива увеличился с 5 до 6. Это естественно и метод size() это показал. Но реальный размер массива увеличился с 5 до 7, о чем показал метод capacity() . То есть, выделилось на 1 элемент больше.
Вызов метода shrink_to_fit() перераспределил память так, что количество выделенной памяти под элементы стала равна количеству памяти, занятой элементами.
6. Метод resize() . Изменить размер массива
Метод resize() позволяет изменять размер динамического массива в большую или в меньшую сторону. Метод имеет две перегруженные реализации.
Первая реализация имеет следующее объявление
- _NewSize – новый размер массива. Если _NewSize больше текущего размера массива, то все остальные элементы дополняются нулевыми значениями.
Вторая реализация имеет следующее объявление
- _NewSize – новый размер массива;
- T – тип элементов массива;
- Val — значения, которыми дополняются элементы массива в случае, если значение _NewSize больше текущего размера.
Пример.
7. Метод reserve() . Зарезервировать дополнительную память для элементов массива
Метод reserve() позволяет выделить (зарезервировать) память для элементов массива, которая возвращается методом capacity() . Реальное количество элементов в массиве, которое возвращается методом size() , не изменяется.
Правильное использование метода в программе позволяет ускорить выполнение программы в случаях, когда активно изменяется размер массива (часто выполняются операции добавления, удаления элементов из массива). Это осуществляется за счет уменьшения количества операций, связанных с перераспределением памяти.
Как расширить вектор в C++?
Программирование и разработка
Если «развернуть» здесь означает включить в вектор больше элементов, чтобы его размер (длина) увеличился, то вектор может быть расширен. Однако «расширение вектора» — не классическая фраза в C ++. Фактически, «расширение» в C ++ фактически означает замену имени объекта значениями его содержимого. Если вектор состоит из строковых литералов, то вектор может быть заменен одной строкой, состоящей из строковых литералов. Однако это нужно делать вручную. То есть это должен делать программист, а не библиотека.
Тем не менее, этот пост объяснит, как заменить вектор строковых литералов одной строкой литералов. В этом посте также будут объяснены различные способы увеличения длины вектора C ++. Длина вектора в C ++ называется размером.
У вектора есть функции-члены. Его размер можно увеличить с помощью функций-членов: resize (), insert (), emplace () и push_back (). В этой статье объясняются различные способы расширения вектора, то есть увеличения его размера; а в случае вектора строковых литералов заменяется всеми строковыми литералами.
Выполняйте векторное кодирование внутри тела функции main (), если нет веской причины сделать это перед телом функции main (). Не забудьте начать программу с:
Вектор строк в одну строку
Вектор строковых литералов можно заменить одной строкой литералов. Литералы будут разделены запятыми в одной строке. Следующий код иллюстрирует это:
vectorvtr = < «Toyota» , «Mitsubishi» , «Ford» , «Mercedes» , «Jeep» >;
char arrChars [ 100 ] ;
int ctr = 0 ; //counter
int i = 0 ;
for ( i = 0 ; i < vtr. size ( ) ; i ++ ) <
const char * str = vtr [ i ] ;
int j = 0 ;
for ( j = 0 ; str [ j ] != ‘ \0 ‘ ; j ++ ) <
arrChars [ ctr ] = str [ j ] ;
++ ctr ;
>
arrChars [ ctr ] = ‘,’ ; ++ ctr ; arrChars [ ctr ] = ‘ ‘ ;
++ ctr ;
>arrChars [ ctr ] = ‘ \0 ‘ ;
cout << arrChars << endl ;
это одна длинная строка. Строка массива и строковый литерал в двойных кавычках по сути одно и то же, заканчиваясь на ’\ 0′; хотя окончание строкового литерала в двойных кавычках неявно. Последняя длинная строка имеет только один ’\ 0′ в конце последовательности символов. Код все еще можно изменить, удалив последнюю запятую и пробел.
Увеличение размера вектора
Изменение размера
Функцию-член size () можно использовать для возврата size () вектора, как показано в следующем коде:
Чтобы увеличить размер вектора, его нужно увеличить до большего числа. Следующий код делает это с помощью функции-члена resize (size_type sz):
Когда размер вектора просто изменяется с помощью функции-члена resize (), новые пустые местоположения становятся доступными ближе к концу вектора. Затем эти новые места можно заполнить.
То же значение можно добавить к новым местоположениям ближе к концу вектора, используя этот перегруженный метод resize (). Иллюстрация:
Вставка
Вставка происходит перед элементом, на который указывает итератор.
Следующий код показывает, как используется эта функция:
«Z» вставлено перед буквой H. Функция-член begin () возвращает итератор, указывающий на первый элемент вектора. Затем итератор может быть увеличен до желаемой позиции. Обратите внимание, что ожидаемый второй аргумент для insert () здесь — идентификатор.
Следующий код показывает, как используется эта функция:
«Z» вставлено перед буквой H. Функция-член begin () возвращает итератор, указывающий на первый элемент вектора. Обратите внимание, что ожидаемый второй аргумент для insert () здесь — литерал.
Одно и то же значение можно вставить более одного раза. Следующий код иллюстрирует это:
вставка итератора (позиция const_iterator, сначала InputIterator, затем — InputIterator)
Может быть вставлен диапазон из другого вектора. Следующий код иллюстрирует это:
Для другого вектора диапазон получается следующим образом: функция-член begin () возвращает итератор, указывающий на свой первый элемент. Этот итератор, я был увеличен, чтобы указывать на следующий элемент. Функция-член end () возвращает итератор, который указывает сразу после последнего элемента. Этот итератор j был дважды уменьшен путем вычитания из него 2, а затем указывал на элемент «N».
На данный момент предполагаемый диапазон:
Однако в C ++ последний элемент диапазона не будет задействован (вставлен). Итак, вставляются только «L», «M».
Можно вставить список векторных литералов. Следующий код иллюстрирует это:
Emplace
Использование emplace () аналогично использованию insert (), и многие программисты предпочитают использовать insert ().
Emplace within
В следующем коде «Z» помещается в значения «F», «G», «H», «I», «J»:
Emplace in front
Для следующего кода «Z» помещается перед значениями «F», «G», «H», «I», «J»:
Итератор, возвращаемый функцией begin (), не увеличивался; и поэтому вывод:
Push_Back
Функция-член push_back () может использоваться для добавления элемента. Следующий код иллюстрирует это:
Элемент также можно добавить с помощью функции-члена emplace_back (). Следующий код иллюстрирует это:
Зная длину вектора
Размер вектора означает количество элементов в векторе. Это можно получить с помощью функции-члена size (). Следующая программа иллюстрирует это:
Емкость вектора
Емкость вектора не следует путать с размером вектора. Когда вектор манипулируется и увеличивается, расположение его элементов в памяти компьютера изменяется (перераспределяется). Емкость вектора — это общее количество элементов, которые вектор может содержать без необходимости перераспределения. Он откладывается с начальным размером вектора. Следующая программа иллюстрирует это для пустого вектора и для вектора из 5 элементов:
Reserving Space for Vector
С помощью этой функции можно зарезервировать векторное пространство. Следующая программа резервирует место из 5 элементов:
#include
#include
using namespace std ;
int main ( )
<
vectorvtr = < ‘F’ , ‘G’ , ‘H’ >;vtr. reserve ( 5 ) ;
int cap = vtr. capacity ( ) ;cout << «New Capacity: « << cap << endl ;
vtr. push_back ( ‘I’ ) ;
vtr. push_back ( ‘J’ ) ;
vtr. push_back ( ‘K’ ) ;for ( int i = 0 ; i < vtr. size ( ) ; i ++ ) <
cout << vtr [ i ] << ‘ ‘ ;
>
cout << endl ;return 0 ;
>
Зарезервированные пробелы включают те, которые предназначены для начальных элементов. Тот факт, что было зарезервировано 5 пробелов, не означает, что к элементу нельзя добавить более 5 элементов.
Заключение
«Расширение вектора» — это не классическая фраза в C ++. Однако, если «расширение вектора» означает увеличение длины вектора, тогда, да, вектор может быть расширен. В C ++ длина вектора или любого контейнера C ++ называется размером. Вектор можно расширить с помощью следующих функций-членов: resize (), insert (), emplace () и push_back (). Другие связанные функции-члены: size (), capacity () и reserve (). Во многих программах на C ++ вектор будет увеличиваться и уменьшаться в несколько раз. Вектор можно уменьшить, используя функцию-член стирания — см. Ниже. Если вектор состоит из строковых литералов, то вектор можно заменить одной длинной строкой, состоящей из строковых литералов.