是否可以使用 libc 指针将向量转换为嵌套向量?
Is it possible to convert a vector into a nested vector using a libc pointer?
我想把一个向量(Vec<u8>
)变成一个嵌套向量(Vec<Vec<u8>>
),例如:
[1,2,3,4,5,6] -> [[1,2,3], [4,5,6]]
这样做,我不想使用迭代器,collect
或reduce
,我想将Vec
转换成C指针:
let ptr_vec = my_vec.as_ptr() as *const libc::c_void;
然后,将这个伪 char *my_vec
转换成伪 char *my_vec[3]
,这样我就不必通读整个向量了。
这可能吗?如果是这样,它真的能提高大向量的性能吗?
Is it possible ?
没有。您不能 通过指针转换来执行结构更改。在 Vec<u8>
上调用 as_ptr
将为您提供指向 Vec
类型 *const u8
的元素的指针。将其转换为 *const *const [u8; 3]
没有任何意义,因为现在您正试图将其视为指向指向 u8
数组的指针数组的指针。换句话说,您会将 u8
s 解释为 指向不存在数组的指针。
更糟糕的是,即使这个 确实 有效,如果你将这个指针转换回 Vec<Vec<u8>>
,你会在你开始重新分配东西的那一刻崩溃,因为你' d 在多个 Vec
之间分割了原始 Vec
的 单个 分配的所有权。这是一个问题,因为您不能 分割分配的所有权;每个 Vec
都会尝试释放整个内存块。
To do so, I don't want to use Iterators, ...
我想不出有什么理由不为此使用迭代器,因为这个问题的任何有效解决方案都等同于:
fn main() {
let v = vec![1,2,3,4,5,6];
let vs = v.chunks(3).collect::<Vec<_>>();
println!("{:?}", vs);
}
鉴于您所说的,我敢打赌您并不是真的想要 Vec<Vec<u8>>
,而是想要 index您的数据就好像它是一个二维矩形矩阵(即所有行具有相同长度的矩阵)。我假设您不想每次都编写实际的公式 (row*stride+col
)。 http://crates.io 上可能有一些有用的东西,但如果你想自己做,你可以将你的 Vec<u8>
包装成一个结构:
struct VecWrapper {
stride: usize,
data: Vec<u8>,
}
impl VecWrapper {
fn get (&self, row: usize, col: usize) -> u8 {
self.data[row*self.stride + col]
}
fn set (&self, row: usize, col: usize, val: u8) {
self.data[row*self.stride + col] = val;
}
}
或者您可以实现 Index
和 IndexMut
特征以通过 []
运算符进行索引(尽管您将需要使用元组索引,并且使用看起来像 array[(row, col)]
)
我想把一个向量(Vec<u8>
)变成一个嵌套向量(Vec<Vec<u8>>
),例如:
[1,2,3,4,5,6] -> [[1,2,3], [4,5,6]]
这样做,我不想使用迭代器,collect
或reduce
,我想将Vec
转换成C指针:
let ptr_vec = my_vec.as_ptr() as *const libc::c_void;
然后,将这个伪 char *my_vec
转换成伪 char *my_vec[3]
,这样我就不必通读整个向量了。
这可能吗?如果是这样,它真的能提高大向量的性能吗?
Is it possible ?
没有。您不能 通过指针转换来执行结构更改。在 Vec<u8>
上调用 as_ptr
将为您提供指向 Vec
类型 *const u8
的元素的指针。将其转换为 *const *const [u8; 3]
没有任何意义,因为现在您正试图将其视为指向指向 u8
数组的指针数组的指针。换句话说,您会将 u8
s 解释为 指向不存在数组的指针。
更糟糕的是,即使这个 确实 有效,如果你将这个指针转换回 Vec<Vec<u8>>
,你会在你开始重新分配东西的那一刻崩溃,因为你' d 在多个 Vec
之间分割了原始 Vec
的 单个 分配的所有权。这是一个问题,因为您不能 分割分配的所有权;每个 Vec
都会尝试释放整个内存块。
To do so, I don't want to use Iterators, ...
我想不出有什么理由不为此使用迭代器,因为这个问题的任何有效解决方案都等同于:
fn main() {
let v = vec![1,2,3,4,5,6];
let vs = v.chunks(3).collect::<Vec<_>>();
println!("{:?}", vs);
}
鉴于您所说的,我敢打赌您并不是真的想要 Vec<Vec<u8>>
,而是想要 index您的数据就好像它是一个二维矩形矩阵(即所有行具有相同长度的矩阵)。我假设您不想每次都编写实际的公式 (row*stride+col
)。 http://crates.io 上可能有一些有用的东西,但如果你想自己做,你可以将你的 Vec<u8>
包装成一个结构:
struct VecWrapper {
stride: usize,
data: Vec<u8>,
}
impl VecWrapper {
fn get (&self, row: usize, col: usize) -> u8 {
self.data[row*self.stride + col]
}
fn set (&self, row: usize, col: usize, val: u8) {
self.data[row*self.stride + col] = val;
}
}
或者您可以实现 Index
和 IndexMut
特征以通过 []
运算符进行索引(尽管您将需要使用元组索引,并且使用看起来像 array[(row, col)]
)