pha*_*hor 5 arrays malloc rust
我对 Rust 很陌生,我想实现一个 2D 地图。因此,我有一个具有内部宽度、高度和未知大小的数据指针的映射结构,直到调用解析文件的 load_map 函数,然后初始化映射结构。在C语言中我会这样做:
struct map {
uint32_t width;
uint32_t height;
uint8_t *data;
};
int load_map(struct map *m)
{
... parse a file and found a map with height=width=8
m->width = 8;
m->height = 8;
// allocate map data using the map size we found
m->data = (uint8_t *)malloc(m->width * m->height);
...
}
Run Code Online (Sandbox Code Playgroud)
在 Rust 中,我不知道如何实现这么简单的事情!这是我失败的尝试:
struct Map<'a> {
width: usize,
height: usize,
data: &'a mut u8
}
fn load_map() -> Map<'static>
{
//code that parse a file and found a map with height=width=8
...
const w:usize = 8;
const h:usize = 8;
//allocate the map data
let mut data = [0;w*h];
// create the map structure
let mut m = Map {
width: w,
height: h,
data: data
};
m
}
fn main() {
let mut m: Map;
m = load_map();
println!("Hello, world! {} {}", m.height, m.width);
}
Run Code Online (Sandbox Code Playgroud)
但货物不高兴并向我抛出这个错误:
error[E0308]: mismatched types
--> src/main.rs:16:15
|
16 | data: data
| ^^^^ expected `&mut u8`, found array `[{integer}; 64]`
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
我确实理解这个错误:rust 期望数据具有相同类型的数据。但我不知道如何实现这一目标。Map 结构是通用的,在解析文件之前我们无法知道数据大小。看来我们应该能够在 init_map 中声明数据字节并将所有权赋予 Map 结构,对吗?但如何呢?
免责声明:我自己对 Rust 很陌生;我只是碰巧正在研究这个完全相同的问题,因此学到了一些关于它的知识。除了我在这里建议的之外,可能还有更好的解决方案或替代方案。
如果在 C 中你有一个指向数组的指针
uint8_t *data;
Run Code Online (Sandbox Code Playgroud)
它由malloc包含结构初始化并期望具有相同的生命周期,那么你在 Rust 中编写它的方式不是data: &u8:
data: Box<[u8]>,
Run Code Online (Sandbox Code Playgroud)
这与您的尝试有两个不同之处:
[u8]而不是u8,因此它存储了许多元素而不是仅仅一个。Box<...>代替了&...,因此它拥有它所指的内容。创建 Box 会在堆上分配其内容,因此直接对应于 的使用malloc。在这里,我修改了您的代码以显示此工作原理并处理所有警告:
struct Map {
width: usize,
height: usize,
data: Box<[u8]>,
}
fn load_map() -> Map {
const W: usize = 8;
const H: usize = 8;
//allocate the map data
let data = [0;W*H];
// create the map structure
let m = Map {
width: W,
height: H,
data: Box::new(data)
};
m
}
fn main() {
let m: Map = load_map();
println!("Hello, world! {} {} {}", m.height, m.width, m.data[0]);
}
Run Code Online (Sandbox Code Playgroud)
还要注意,显式的生命周期参数<'a>和'static消失了;现在不需要它们,并且它们不会起作用(因为函数分配的东西不能起作用'static,除非您选择泄漏它)。
但是,这仍然需要const宽度和高度来构造数组,一旦从地图文件中读取宽度和高度,数组就无法工作。为了解决这个问题,您需要以不同的方式构造数组(或更准确地说,数组切片);一种选择是使用Vec构造函数(然后将其简化为数组切片,因为您不打算更改长度):
data: vec![0; w * h].into_boxed_slice(),
Run Code Online (Sandbox Code Playgroud)