Динамическое создание std :: vector // создание указателя на вектор - PullRequest
1 голос
/ 27 августа 2011

Я новичок, поэтому, скорее всего, я что-то упустил.

Я использую std :: vector для хранения данных из операции ReadFile.

В настоящее время у меня есть структура READBUFF, которая содержит вектор байта. Затем создается экземпляр READBUFF через закрытый тип в классе с именем Reader.

class Reader{
public:
void Read();
typedef struct {
std::vector<byte> buffer;
} READBUFF;

private:
READBUFF readBuffer;
}

В Read () я в настоящее время изменяю размер массива до желаемого размера, так как распределитель по умолчанию создает действительно большой вектор [4292060576]

void Reader::Read()
{
readBuffer.buffer.resize(8192);
}

Это все работает нормально, но потом я решил, что предпочел бы динамически НОВЫЙ вектор, встроенный в вектор, поэтому я контролирую управление распределением указателя. Я изменил буфер на: std :: vector * buffer. Когда я пытаюсь сделать следующий буфер не установлен в новый буфер. Из отладчика ясно, что он не инициализирован.

void Reader::Read()
{
 key.buffer =  new std::vector<byte>(bufferSize);
}

Итак, я попытался, но это ведет себя так же, как указано выше.

void Reader::Read()
{
std::vector<byte> *pvector = new std::vector<byte>(8192);
key.buffer = pvector;
}

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

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

 std::vector<byte> newBuffer(pKey->buffer);
 pKey->ptrFileReader->getBuffer()->Enqueue(newBuffer);

Заранее спасибо. Когда я публикую это, я понимаю, что упустил что-то фундаментальное, но я в растерянности.

Ответы [ 2 ]

6 голосов
/ 27 августа 2011

Вы не должны использовать new в этом случае.Это приводит к тому, что вам приходится управлять памятью вручную, а это никогда , что вам следует делать по многим причинам 1 .Вы сказали, что хотите управлять временем жизни вектора с помощью new;в действительности время жизни вектора уже управляется , поскольку оно совпадает с объектом, в котором он находится.Таким образом, время жизни этого вектора - это время жизни экземпляра вашего класса Reader.

Чтобы установить размер вектора до его построения, вам нужно будет создать конструктор для READBUFF:

// inside the READBUFF struct (assuming you're using a normal variable, not a pointer)
READBUFF() { } // default constructor
READBUFF(int size) : buffer(size) { } // immediately sets buffer's size to the argument 

и используйте список инициализации в конструкторе Reader:

// inside the Reader class
Reader() : readBuffer(8092) { }

, который установит размер readBuffer.buffer в 8092.

Если вы действительно хотите использовать new только для обучения:

key.buffer =  new std::vector<byte>(bufferSize);

Это будет хорошо работать, но вы не должны делать это в функции Read, вы должны делать это в конструкторе объекта.Таким образом, любая функция-член может использовать ее, не проверяя, является ли она NULL.

, так как распределитель по умолчанию создает действительно большой вектор [4292060576]

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

1 Некоторые причины:

  1. Вы должны убедиться, что выделите его, прежде чем кто-либо еще используетэто, где с обычной переменной-членом это делается автоматически, прежде чем ваш объект сможет использовать ее.
  2. Вы должны запомнить delete это в деструкторе.
  3. Если вы неЕсли вы делаете 2 вышеуказанных действия, у вас есть ошибка или утечка памяти.
2 голосов
/ 27 августа 2011

Я думаю, вы можете неправильно интерпретировать результат вызова max_size() для вектора:

#include <vector>
#include <iostream>

int main() {
  std::cout << std::vector<char>().max_size() << std::endl;
  std::cout << std::vector<char>::size_type(~0) << std::endl;
}

Эта программа печатает максимально возможный размер вектора, а не текущий размер.size() с другой стороны печатает текущий размер (игнорируя все, что было зарезервировано).

...