Можно ли преобразовать вектор во вложенный вектор с помощью указателя libc?
Хочу повернуть вектор (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]
так что мне не нужно читать весь мой вектор.
Это возможно? Если да, действительно ли это увеличивает производительность на огромных векторах?
2 ответа
Учитывая то, что вы сказали, я готов поспорить, что вы действительно не хотите Vec<Vec<u8>>
, но вам нужен способ индексировать ваши данные, как если бы это была 2D прямоугольная матрица (т. е. матрица, в которой все строки имеют одинаковую длину). И я предполагаю, что вы не хотите писать фактическую формулу (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)]
)
Является ли это возможным?
Нет. Вы не можете выполнить структурные изменения, такие как приведение указателя. призвание as_ptr
на Vec<u8>
получите указатель на Vec
элементы типа *const u8
, Приведение к *const *const [u8; 3]
не имеет смысла, потому что теперь вы пытаетесь рассматривать его как указатель на массив указателей на массивы u8
, Другими словами, вы будете интерпретировать u8
s как указатели на несуществующие массивы.
Хуже, даже если это сработало, если вы конвертировали этот указатель обратно в Vec<Vec<u8>>
, вы потерпите крах, как только начнете освобождать вещи, потому что вы бы разделили владение одним выделением оригинала Vec
между несколькими Vec
s. Это проблема, потому что вы не можете разделить владение распределением; каждый Vec
будет пытаться освободить весь кусок памяти.
Для этого я не хочу использовать итераторы,...
Я не могу думать ни о какой причине, чтобы не использовать итераторы для этого, учитывая, что любое правильное решение этой проблемы будет эквивалентно:
fn main() {
let v = vec![1,2,3,4,5,6];
let vs = v.chunks(3).collect::<Vec<_>>();
println!("{:?}", vs);
}