Я новичок в Rust и изучаю векторную реализацию. Я много раз пытался изменить размер вектора и проверить адреса элементов с помощью следующего кода:
fn main() {
let mut vector = Vec::new();
for i in 1..100 {
println!(
"Capacity:{}, len: {}, addr: {:p}",
vector.capacity(),
vector.len(),
&vector,
);
vector.push(i);
}
println!("{:p}", &vector[90]);
}
Это дает мне вывод (последние 2 строки):
Capacity:128, len: 98, addr: 0x7ffebe7a6930
addr of 90-element: 0x5608b516bd08
Мой вопрос: почему 90-й элемент находится в другом месте памяти? Я предполагаю, что это должно быть где-то рядом с адресом 0x7ffebe7a6930
.
@BlackBeans Это неверно, Vec::new()
задокументировано, что он не выделяется. См. третий абзац здесь.
@IanS. ах, ну, мой плохой.
Да Vec
хранит свои данные в непрерывном разделе памяти. &vector
дает вам ссылку на реальную структуру Vec
, которая находится в стеке и содержит емкость, указатель и длину. Если вместо этого вы напечатаете vector.as_ptr()
, вы должны получить более понятный результат. Кроме того, вам, вероятно, следует нажать перед печатью в цикле, поскольку теоретически этот вызов push
может перераспределиться на последней итерации, и тогда ваши указатели будут выглядеть другими.
В дополнение к ответу @IanS., имейте в виду, что когда вы вызываете
Vec::new()
, он предварительно выделяет некоторую память, и даже если он, вероятно, выделяет менее 100 элементов, он все равно может выделять больше и просто никогда не перераспределять. Может быть, ради эксперимента вам стоит начать сVec::with_capacity(1)
или чего-то в этом роде.