patternrustMajor
How should you do pointer arithmetic in Rust?
Viewed 0 times
youhowpointerarithmeticshouldrust
Problem
I know the answer is "you shouldn't"... but for the sake of argument, how should you do it?
For example, if you wanted to write an alternative to
I see that you can make 'something that compiles and runs' by transmuting
-
Will a
-
Does
-
This only works because I'm using a primitive type (
-
Is this really the right way of doing this? It seems extremely awkward. I was expecting to find some unsafe
Example
```
extern crate libc;
use std::mem::size_of;
use std::ptr::write;
use std::ptr::read;
use std::mem::transmute;
use libc::calloc;
use libc::free;
use libc::c_void;
struct Array {
length: usize,
data: *mut f64,
}
impl Array {
fn new(length: usize) -> Array {
unsafe {
Array {
length: length,
data: calloc(size_of::(), length) as *mut f64,
}
}
}
fn set(&mut self, offset: usize, value: f64) {
if offset (self.data) +
(size_of::() * offset) as u64);
println!("Write: [{:?}] -> {}", root, value);
write(root, value);
}
} else {
println!("Write: Nope: [{}] is out of bounds", offset);
}
}
fn get(&self, offset: usize) -
For example, if you wanted to write an alternative to
Vec that worked differently.I see that you can make 'something that compiles and runs' by transmuting
mut T values into u64 and adding to them, then transmuting them back into mut T and reading the value at the pointer (see example below). It seems to work, but it leaves a few of open questions:-
Will a
* mut T pointer always fit into u64?-
Does
write()ing to an unsafe pointer trigger pointer aliasing issues when the data is an arbitrary (i.e. not a managed type) data block from libc:calloc?-
This only works because I'm using a primitive type (
f64). If this was a real data object, I would have to forget() the object first; but can you simply write() a * mut T into a target and then happily read() it out again later if the type is complex and has child records?-
Is this really the right way of doing this? It seems extremely awkward. I was expecting to find some unsafe
ptrtoint() / inttoptr() pair, but I can't find anything like that. Example
```
extern crate libc;
use std::mem::size_of;
use std::ptr::write;
use std::ptr::read;
use std::mem::transmute;
use libc::calloc;
use libc::free;
use libc::c_void;
struct Array {
length: usize,
data: *mut f64,
}
impl Array {
fn new(length: usize) -> Array {
unsafe {
Array {
length: length,
data: calloc(size_of::(), length) as *mut f64,
}
}
}
fn set(&mut self, offset: usize, value: f64) {
if offset (self.data) +
(size_of::() * offset) as u64);
println!("Write: [{:?}] -> {}", root, value);
write(root, value);
}
} else {
println!("Write: Nope: [{}] is out of bounds", offset);
}
}
fn get(&self, offset: usize) -
Solution
Pointers have an
Output
https://doc.rust-lang.org/nightly/book/first-edition/unsafe.html
offset method for pointer arithmetic.fn main() {
let items = [1usize, 2, 3, 4];
let ptr = &items[1] as *const usize;
println!("{}", unsafe { *ptr });
println!("{}", unsafe { *ptr.offset(-1) });
println!("{}", unsafe { *ptr.offset(1) });
}Output
2
1
3
https://doc.rust-lang.org/nightly/book/first-edition/unsafe.html
Code Snippets
fn main() {
let items = [1usize, 2, 3, 4];
let ptr = &items[1] as *const usize;
println!("{}", unsafe { *ptr });
println!("{}", unsafe { *ptr.offset(-1) });
println!("{}", unsafe { *ptr.offset(1) });
}Context
Stack Overflow Q#24759028, score: 87
Revisions (0)
No revisions yet.