Как я могу получить адрес буфера, выделенного vector:: reserve()?
У меня есть std::vector значений, для которых я знаю максимальный размер, но фактический размер будет меняться во время использования:
void setupBuffer(const size_t maxSize) {
myVector.reserve(maxSize);
}
void addToBuffer(const Value& v) {
myVector.push_back(v);
if (myVector.size() == maxSize) {
// process data...
myVector.clear();
}
}
Однако в setupBuffer мне нужно получить указатель на начало myVector-данных. Я использую стороннюю библиотеку, где я должен кэшировать этот указатель спереди для использования в вызове, сделанном в разделе "данные процесса...".
void setupBuffer(const size_t maxSize) {
myVector.reserve(maxSize);
cachePtr(&(myVector[0])); // doesn't work, obviously
}
Я не хочу изменять размер() перед фронтом, так как я хочу использовать vector.size() для обозначения количества элементов, добавленных в вектор.
Итак, есть ли способ получить указатель на векторный буфер после выделения (reserve()), но до того, как он будет иметь какие-либо элементы? Я бы предположил, что буфер существует (и не будет двигаться, если я ограничу количество значений push_back'd).... возможно, это не гарантируется?
Ответы
Ответ 1
Векторный буфер не будет перемещен после вызова резерва, если вы не превысите зарезервированную емкость. Ваша проблема заключается в получении указателя на первый элемент. Очевидный ответ заключается в том, чтобы подтолкнуть одну фальшивую запись в вектор, получить указатель на нее и затем удалить ее.
Хороший подход был бы, если бы библиотека приняла функтор, а не указатель, который он вызывал бы, когда ему нужно было получить доступ к буферу - вы могли бы заставить функтора отложить получение адреса до тех пор, пока в буфере не будет какое-то реальное содержимое. Однако я понимаю, что у вас нет роскоши переписывать библиотеку.
Ответ 2
Нет. Вам не разрешен доступ к любому элементу в fector с индексом больше size
. Изменение размера - это ваш единственный вариант.
Что вы можете сделать, это что-то вроде:
myvec.resize(SOME_LARGE_VALUE);
myLibrary(&myVec[0]);
myvec.resize(GetSizeUsedByLibrary());
При изменении размера элементы в векторе не уничтожаются, кроме тех, которые имеют индекс выше нового размера. Элементы ниже числа, установленного в размере, остаются в силе. Пример использования std::basic_string
, но в равной степени применимый к вектору
Ответ 3
Вы попробовали front()? Кроме того, вы можете push_back элемент, получить адрес, как вы, а затем удалить его.
Все это не гарантируется, но вы можете прочитать источник своего вектора < > , чтобы узнать, хорошо ли это для вас, если вам нужно это сделать. Вы также можете легко свернуть свой собственный вектор, который имеет указатель на данные и никогда не перемещает его.
Ответ 4
У него много хаков. Но я рекомендую вам действующий путь - переопределить распределитель, второй аргумент шаблона:
typedef std::vector<MyItem, MyAllocator> myvector_t;
После этого в MyAllocator предусмотрено фиксированное выделение буфера и передается этот экземпляр распределителя как аргумент конструктора векторов