LINUX.ORG.RU

vector vs unique_ptr

 


0

2

Есть много API функций вида getData(void *pvData), которые заполняют буфер (часто - большого размера)
Заполнять этот буфер перед вызовом нет смысла.
По дальнейшему использованию удобнее vector, но он при создании будет инициализировать элементы. Есть способ этого избежать?

★

он при создании будет инициализировать элементы

если писать std::vector<T> v(10); то конечно будет. иначе - не будет.

x0r ★★★★★
()

С помощью unique_ptr удобно передавать право владения объектом, получается самодокументируемый код. Не совсем понял при чем он в твоем вопросе. Касательно вектора, создавай пустой, а потом вызывай reserve.
EDIT: Хотя я не ответил на твой вопрос, после вызова reserve capacity вектора станет подходящего размера и в его память даже можно записать данные, но вот сам вектор об этом будет не в курсе.

m0rph ★★★★★
()
Последнее исправление: m0rph (всего исправлений: 1)

но он при создании будет инициализировать элементы

Я тебе больше скажу, он будет каждый раз копировать элементы.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

unique_ptr он копировать точно не будет.

anonymous
()
Ответ на: комментарий от m0rph

но вот сам вектор об этом будет не в курсе

В том то и дело.

Имеется в виду специализация unique_ptr<T[]>

Или в зависимости от конкретной реализации изменять значение указателя на конец данных?

Uter ★
() автор топика
Последнее исправление: Uter (всего исправлений: 1)
Ответ на: комментарий от no-such-file

копировать элементы

Да, ты прав - я забыл этот момент.

Всё равно ненужный оверхед, если нужен «умный» буфер на N мегабайт

Uter ★
() автор топика
Ответ на: комментарий от Uter

unique_ptr ничего не знает о размере куска памяти, придётся таскать с собой дополнительный параметр или писать небольшую обёртку

Gvidon ★★★★
()

getData(char *pvData, size_t datasize),

fxd.

Если надо массив, то я всегда использую unique_ptr в таких случаях. Если просто указатель на структуру например то shared_ptr.

Вектор имеет смысл использовать, если ты потом будешь что-либо из <algorithm> примерять. foreach например. Или find/sort.

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)

vector vs unique_ptr

Только сейчас допёр, в чем вопрос. Понятнее надо выражать свои мысли, товарищ программист.

По дальнейшему использованию удобнее vector

Т.е. что, надо будет добавлять элементы что-ли?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Он будет копировать только тогда, когда ты ему скажешь.

anonymous
()
Ответ на: комментарий от Gvidon

Как будто в спп нельзя сделать ьталедс или что-то в этом духе.

nanoolinux ★★★★
()
Ответ на: комментарий от Uter

Итераторы

Чем обычные указатели не угодили?

не надо размер отдельно таскать

Простенькая структурка, состоящая из указателя и size_t поля, пишется минут за 5, ты гораздо больше времени тут потратил

Gvidon ★★★★
()
Ответ на: комментарий от crowbar
std::vector<uint8_t> buff(100500);
getData(buff.data());

Удобнее, но конструктор будет занулять 100500 байт

auto buff = std::make_unique<uint8_t[]>(100500);
getData(buff.get());

Нет лишнего зануления, но чуть менее удобно в дальнейшем

Uter ★
() автор топика
Ответ на: комментарий от Gvidon

пишется минут за 5

ну тогда уж за 15 минут копипастится std::vector и переделывается в какой-нибудь mystd::heap_array

Uter ★
() автор топика
Ответ на: комментарий от Uter

Куда таскать размер? Указатели вполне работают как итераторы(собственно, итераторы - это обобщение указателей), так что все стандартные алгоритмы будут доступны.

anonymous
()
Ответ на: комментарий от crowbar

неизвестно сколько мегабайт размещать в стеке?

Uter ★
() автор топика
Ответ на: комментарий от anonymous

ну, либо указатель на конец данных для unique_ptr илибо размер

Uter ★
() автор топика

По дальнейшему использованию удобнее vector, но он при создании будет инициализировать элементы. Есть способ этого избежать?

напиши свой вектор СБИШ

emulek ★
()
Ответ на: комментарий от one_more_hokum

Размер задаётся на этапе компиляции, память выделяется на стеке. std::array вряд ли годится на роль общего решения

Gvidon ★★★★
()
Ответ на: комментарий от AlexVR

Как unique_ptr связан с многопоточность?

anonymous
()
Ответ на: комментарий от Gvidon

std::array вряд ли годится на роль общего решения

No silver bullet, я знаю. Для определённых применений он очень даже OK.

one_more_hokum ★★★
()

Не надо экономить на спичках. Если нужен буфер, используй std::vector<char>. Пускай инициализируется.

Такой код должен быть понятен всем.

Если бы API можно было изменить и если бы заполняемый буфер представлял собой линейных массив объектов одного типа, то проще было бы использовать функцию std::vector<T>::emplace_back() внутри функции getData() и передавать в функцию vector<T>, а не void*.

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 2)

А ещё лучше определиться со стилем кода. Активное использование void*, это не то, что хорошо вяжется с идеологией активного использования контейнеров STL и прочих возможностей современного с++.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

не то, что хорошо вяжется с идеологией активного использования контейнеров STL и прочих возможностей современного с++.

Но вполне в духе сишныйх API

Uter ★
() автор топика
Ответ на: комментарий от Uter

Но вполне в духе сишныйх API

Ну тогда работай в слое взаимодействия с этим API в сишном стиле. Большие ценители «pure C» не имеют дела с STL и таких вопросов не задают.

pathfinder ★★★★
()
Ответ на: комментарий от AlexVR

А потом другим добиться с потоко-безопасностью.

Чё? У меня сегфолт в парсере от этого предложения.

nanoolinux ★★★★
()
Ответ на: комментарий от no-such-file

Я тебе больше скажу, он будет каждый раз копировать элементы.

Reference? std::move?

Deleted
()
5 сентября 2014 г.

Не уверен, но может так не будет делаться инициализация:

std::vector<int> v;
v.resize(count);

andreyu ★★★★★
()
Вы не можете добавлять комментарии в эту тему: топик перемещен в архив.