Задать вопрос
@Sasha_88

При добавление элементов в вектор, при превышении capacity, это приведет к перераспределению Vec?

В примере программы для проверки этого я ожидал, что адрес вектора в куче должен измениться. Если, конечно, я правильно написал программу. Потому, что изначально у вектора нет вообще емкости и я добавляю элементы. По идее тут при превышении емкости больше 16, опять происходит перераспределение. А адрес не меняется. И если бы он менялся, тогда другой вопрос. А откуда компилятор тогда знает по какому адресу ссылаться на элементы вектора после перераспределения? Спасибо.
#![allow(unused)]
fn main() {
    let mut vec = Vec::new();
    assert_eq!(vec.len(), 0);
    
    println!("\n{:?}", &vec);
    println!("\nДлина вектора = {}", vec.len());
    println!("Емкость вектора = {}", vec.capacity());
    
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
   
    assert_eq!(vec.len(), 10);

    println!("\n{:?}", vec);
    println!("\nДлина вектора = {}", vec.len());
    println!("Емкость вектора = {}", vec.capacity());
    println!("Адрес вектора = {:p}", &vec[0]);
    
    vec.push(2);
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
    vec.push(1);
    vec.push(2);
    
    assert_eq!(vec.len(), 17);
    
    println!("\n{:?}", vec);
    println!("\nДлина вектора = {}", vec.len());
    println!("Емкость вектора = {}", vec.capacity());
    println!("Адрес вектора = {:p}", &vec[0]);
}

Вывод
[]

Длина вектора = 0
Емкость вектора = 0

[1, 2, 1, 2, 1, 2, 1, 2, 1, 2]

Длина вектора = 10
Емкость вектора = 16
Адрес вектора = 0x58b235667b10

[1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2]

Длина вектора = 17
Емкость вектора = 32
Адрес вектора = 0x58b235667b10
  • Вопрос задан
  • 72 просмотра
Подписаться 1 Простой 4 комментария
Решения вопроса 1
fenrir1121
@fenrir1121
Начни с документации
При превышении capacity адрес может измениться.
Довольно банальная оптимизация - если впереди необходимая память свободна, расширение происходит на месте, без переноса.

Проверить можно так
fn main() {
    let mut vec = Vec::with_capacity(2);
    let initial_ptr = vec.as_ptr();

    let (new_ptr, new_capacity) = std::iter::repeat(())
        .enumerate()
        .find_map(|(i, _)| {
            vec.push(i as i32 + 3);
            (vec.as_ptr() != initial_ptr).then(|| (vec.as_ptr(), vec.capacity()))
        })
        .unwrap();
    println!("Initial ptr: {:?}", initial_ptr);
    println!("New ptr: {:?}", new_ptr);
    println!("New capacity: {}", new_capacity);
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы