Почему адрес второй переменной не сразу после первой переменной? - PullRequest
0 голосов
/ 10 июля 2019

Мне известно, что в 64-битной системе Vec будет хранить 8-байтовый указатель на кучу, 8 байт для емкости и 8 байт для длины.

Я предполагаю, чтоадрес a находится сразу после адреса v, но когда я проверил границы выделения вектора в стеке, я обнаружил, что он всегда занимает 31 байт стековой памяти, на 7 байт больше, чем следовало бы.То же самое относится и к строкам.

pub fn main() {
    let v = vec![1_u8];
    let a = 1_u8;

    let v_raw = &v as *const _;
    let a_raw = &a as *const _;

    println!("v addr = {:p}, dec = {}", v_raw, v_raw as usize);
    println!("a addr = {:p}, dec = {}", a_raw, a_raw as usize);
    println!("offset = {} bytes", a_raw as usize - v_raw as usize);

    // changing below 3 print will affect the mysterious 7 bytes
    //    println!("v_raw addr = {:p}", &v_raw);     // (1)
    //    println!("a_raw addr = {:p}", &a_raw);     // (2)
    println!("v as_ptr = {:p}", v.as_ptr()); // (3)

    // dereference through offset 24 to 30 -> 7 bytes
    let mut offset = 24_usize;
    loop {
        if offset == 31 {
            break;
        }

        // usize to *const usize(raw pointer)
        let mut addr = (v_raw as usize + offset) as *const usize;
        let deref_value = unsafe { *addr as u8 };

        println!(
            "offset = {}, addr = {:p}, value hex = {:x}, value = {}",
            offset, addr, deref_value, deref_value
        );

        offset += 1;
    }
}
v addr = 0x7fffbcf48b70, dec = 140736363531120
a addr = 0x7fffbcf48b8f, dec = 140736363531151
offset = 31 bytes
v as_ptr = 0x55d9c823ea40
offset = 24, addr = 0x7fffbcf48b88, value hex = 0, value = 0
offset = 25, addr = 0x7fffbcf48b89, value hex = 0, value = 0
offset = 26, addr = 0x7fffbcf48b8a, value hex = 0, value = 0
offset = 27, addr = 0x7fffbcf48b8b, value hex = 0, value = 0
offset = 28, addr = 0x7fffbcf48b8c, value hex = 0, value = 0
offset = 29, addr = 0x7fffbcf48b8d, value hex = 0, value = 0
offset = 30, addr = 0x7fffbcf48b8e, value hex = 0, value = 0

Иногда эти 7 дополнительных адресов содержат все 0 значений, а иногда нет, если я раскомментирую все макросы println!, помеченные (1) (2) (3))

Поскольку я последовательно объявил v и a, я ожидал, что a находится рядом с v в стеке, так почему я получаю эти 7 дополнительных байтов?Эта дополнительная память предназначена для чего-то особенного?

1 Ответ

2 голосов
/ 10 июля 2019

Я предполагаю, что адрес a находится сразу после адреса v.

То, что вы записали эти переменные в таком порядке, не означает, что Rust будет хранитьих последовательно в стеке.Компилятор Rust может свободно размещать вещи в памяти там, где он считает нужным, и вы абсолютно не можете полагаться на порядок.Окончательный порядок может отличаться в зависимости от:

  • версии компилятора Rust
  • , если вы компилируете для отладки или выпуска
  • целевой операционной системы
  • целевая архитектура процессора
  • другой код поблизости в вашем приложении

Фактический размер Vec может быть показан равным 24:

let v = vec![1_u8];
println!("size = {}", std::mem::size_of_val(&v)); // size = 24

См. Также:

...