Ржавчина выделяет расположение памяти, не соответствующее размеру - PullRequest
1 голос
/ 14 октября 2019

Я, должно быть, что-то неправильно понимаю, но я написал простой кусок кода для проверки адресов памяти и получаю странные результаты:

Вот код:

use std :: alloc:: {alloc, Layout};

fn main() {
    let r1 : *mut i32;
    let r2 : *mut i32;
    let r3 : *mut i32;
    let r4 : *mut u8; 
    let r5 : *mut i32;
    unsafe { 
        r1 = alloc(Layout::new::<i32>()) as *mut i32;
        r2 = alloc(Layout::new::<i32>()) as *mut i32;
        r3 = alloc(Layout::new::<i32>()) as *mut i32;
        r4 = alloc(Layout::new::<i8>()); 
        r5 = alloc(Layout::new::<i32>()) as *mut i32;
    }   
    println!("Raw pointer r1: {:p}", r1);
    println!("Raw pointer r2: {:p}", r2);
    println!("Raw pointer r3: {:p}", r3);
    println!("Raw pointer r4: {:p}", r4);
    println!("Raw pointer r5: {:p}", r5);
}  

и когда я запускаю его, я получаю:

Raw pointer r1: 0x7fdb17402a60
Raw pointer r2: 0x7fdb17402a70
Raw pointer r3: 0x7fdb17402a80
Raw pointer r4: 0x7fdb17402a90
Raw pointer r5: 0x7fdb17402aa0

Два вопроса:

  1. IПосмотрите, что согласно документам i32 занимают 4 байта, так почему разница в адресном пространстве между r1 и r2 равна 0x10, а не 0x04? Тот же вопрос для случаев между r4 и r5, где я ожидал только 1-байтовое смещение.

  2. Почему * mut 8, который возвращает alloc, достаточно в качестве указателя? Мы не сможем представить 64-битные адреса виртуальной памяти, используя только байты, верно?

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

1 Ответ

1 голос
/ 14 октября 2019

Этот вопрос не является специфическим для ржавчины, а скорее вопросом, как работает распределение памяти. Распределители памяти должны:

  • учитывать требования выравнивания базовой архитектуры ... например, возвращаемый указатель может пожелать делиться на размер слова процессора;

  • сохранить размер выделенного пространства (для целей отмены выделения)

Таким образом, рассмотрите возможность выделения одного 32-разрядного целого числа ... распределитель пожелаетвыделить место для хранения:

  1. слово для хранения размера выделенного пространства;
  2. 32-разрядное целое число (которое в данном случае занимает половину слова)

Поскольку при распределении требуется выравнивание слов, следующее выделение произойдет через два слова или 16 байт после первого.

Что касается вашего второго вопроса, * mut u8 не занимает ни одногобайт, как и значение, которое демонстрирует данный код, напечатанный для него.

...