вектор и сброс - PullRequest
       35

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

1 голос
/ 28 января 2009

Из того, что я знаю, вектор гарантированно будет непрерывным, и я могу записать в него кусок памяти и отправить с ним 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 ]

4 голосов
/ 28 января 2009
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".

2 голосов
/ 29 января 2009

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

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

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

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

2 голосов
/ 28 января 2009

Действительно, 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.

0 голосов
/ 28 января 2009

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

vector<char> v2

с

vector<Type> v2

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

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

0 голосов
/ 28 января 2009

Да, вы используете вектор 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);
...