Вектор и сброс

Из того, что я знаю, вектор гарантированно будет непрерывным, и я могу записать в него кусок памяти и сделать с ним fwrite. Все, что мне нужно сделать, это убедиться, что я вызову.resize(), чтобы заставить его быть минимальной длины, в которой я нуждаюсь, тогда я могу использовать его как обычный массив символов? будет ли этот код правильным

v.resize(numOfElements);
v.clear(); //so i wont get numOfElements + len when i push back
vector<char>v2;
v2.resize(numOfElements*SizeOfType);
while(...)
{
...
v.push_bacK(x); 
}
compress(&v2[0], len, &v[0], len);
fwrite(&v2[0], ....)

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

5 ответов

Решение
v.resize(numOfElements);
v.clear(); //so i wont get numOfElements + len when i push back

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

v.reserve(numOfElements);

Просто этот код намного быстрее. Так, v.size() == 0 в обоих случаях и v.capacity() может быть таким же, как numOfElements в обоих случаях тоже (хотя это не гарантировано). Во втором случае, однако, емкость по крайней мере numOfElements, что означает, что внутренний буфер не будет перераспределен до тех пор, пока вы не поместите столько элементов в вектор. Обратите внимание, что в обоих случаях это недопустимо, если вы пытаетесь получить доступ к каким-либо элементам - потому что фактически содержится нулевой элемент.

Кроме того, я не понял проблемы в вашем коде. Это безопасно, и я бы посоветовал использовать его вместо сырого new или же malloc из-за дополнительной безопасности это обеспечивает. Я, однако, не уверен, что вы подразумеваете под "дамп v".

Действительно, std::vector гарантированно будет смежным, чтобы быть совместимым с компоновкой с массивом C. Однако вы должны знать, что многие операции с вектором делают недействительными все указатели, указывающие на его элементы, поэтому вам лучше придерживаться одного типа использования: избегайте смешивания арифметики с указателями и вызовов методов для вектора.

Кроме того, это совершенно правильно, за исключением первой строки: то, что вы хотите, это

v.reserve(numOfElements);

который выделит достаточно места для хранения numOfElements в вектор, тогда как

v.resize(numOfElements);

сделаю следующее:

// pseudo-code
if (v.size() < numOfElements)
    insert (numOfElements - size) elements default 
    constructed at the end of the vector

if (v.size() > numOfElements)
    erase the last elements so that size = numOfElements

Подводя итог, после reserve Вы уверены, что емкость вектора больше или равна numOfElements, и после resize Вы уверены, что размер вектора равен numOfElements.

Для чего-то подобного я бы лично использовал класс типа STLSoft auto_buffer<>:

В качестве отказа от ответственности - я не использую реальную версию библиотеки STLSoft, я адаптировал свой собственный шаблон, который очень похож - я начал с книги Мэтью Уилсона (автора STLSoft) "Несовершенный C++".

Я нахожу это полезным, когда я действительно хочу просто старый массив C, но размер должен быть динамическим во время выполнения. auto_buffer<> безопаснее, чем обычный старый массив, но после того, как вы его сконструировали, вас не будет беспокоить, сколько там элементов или нет - это всегда то, с чем вы его построили, как массив (так что это немного менее сложно, чем vector<> - что уместно время от времени).

Основным недостатком auto_buffer<> в том, что он не стандартный и не в Boost, поэтому вам нужно либо включить часть STLSoft в свой проект, либо выпустить собственную версию.

Вы заменяете Reserve() изменением размера, вы также можете заменить

vector<char> v2

с

vector<Type> v2

Это должно немного упростить код.

Честно говоря, это самое странное использование векторов, которое я когда-либо видел, но это, вероятно, сработает. Вы уверены, что не хотите использовать новый символ [размер] и какой-нибудь автоматический указатель от boost?

Да, вы используете вектор char в качестве буфера для чтения необработанного ввода.

// dynamically allocates a buffer of 10,000 char as buffer
std::vector<char>   data(10000);

fread(&data[0], sizeof(char),data.size(),fp);

Я бы не стал использовать его для чтения любого типа данных, отличного от POD, непосредственно в вектор.

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

fwrite(&data[0], sizeof(char),data.size(),fp);
Другие вопросы по тегам