Действителен ли следующий код std :: vector? - PullRequest
4 голосов
/ 05 марта 2010
std::vector<Foo> vec;
Foo foo(...);

assert(vec.size() == 0);
vec.reserve(100); // I've reserved 100 elems
vec[50] = foo; // but I haven't initialized any of them
// so am I assigning into uninitialized memory?

Безопасен ли вышеуказанный код?

Ответы [ 5 ]

7 голосов
/ 05 марта 2010

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

Дело в том, что вы не можете изменить размер вектора, не инициализировав элементы (даже если только инициализация по умолчанию).

4 голосов
/ 05 марта 2010

Вы должны использовать vec.resize(100), если хотите сразу внести индекс.

vec[50] безопасно только если 50 < vec.size(). reserve() не изменяет размер вектора, но resize() делает и создает содержащийся тип.

0 голосов
/ 05 марта 2010

Прежде чем вы сможете использовать operator [] для доступа к 50-му элементу, вы должны либо вызвать функцию resize, push_back () что-то 50 раз, либо использовать алгоритм std :: fill_n.

0 голосов
/ 05 марта 2010

std :: vector :: reserve (100) потребует 100 * sizeof (Foo) свободной памяти, так что дальнейшая вставка в вектор не будет выделять память до тех пор, пока 100 * sizeof (foo) не будет заполнен, но доступ элемент этого вектора даст недетерминированное содержимое этого элемента, поскольку его единственное утверждение - память не выделяет его.

0 голосов
/ 05 марта 2010

Это не сработает. Хотя контейнер имеет 100 зарезервированных элементов, он по-прежнему содержит 0 элементов.

Вам необходимо вставить элементы, чтобы получить доступ к этой части памяти. Как сказал Джон-Эрик, resize() - это путь.

...