1

I must be misunderstanding something here but I wrote a simple piece of code to test memory addresses and am getting some strange results:

Here is the code:

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);
}  

and when I run it I get:

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

Two questions:

  1. I see that according to the docs i32s take up 4 bytes, so why is the address space difference between r1 and r2 0x10 instead of 0x04? Same question for cases between r4 and r5 where I expected only a 1 byte offset.

  2. Why is *mut 8, which is what alloc returns, sufficient as a pointer? We would not be able to represent the 64 bit virtual memory addresses using just a byte right?

I'm trying to learn these unsafe aspects of rust because there I will be working on some kernel related project and it is necessary to work with raw pointers.

1
  • A *mut u8 does not occupy a single byte ... Commented Oct 14, 2019 at 5:38

1 Answer 1

2

This question is not rust specific but rather a question regarding how memory allocation works. Memory allocators need to:

  • consider the alignment requirements of the underlying architecture ... for example, the returned pointer may wish to be divisible by the processor word size;

  • store the size of the allocated space (for de-allocation purposes)

Thus consider allocating a single 32-bit integer ... the allocator will wish to allocate space to store:

  1. a word for storing the size of the space allocated;
  2. the 32-bit integer (which takes half a word in this case)

As allocation wishes to be word aligned, the next allocation will occur two words, or 16 bytes, after the first.

As to your second question, a * mut u8 does not occupy a single byte, as surely the value the given code printed for it demonstrates.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.