在链表节点间复制数据



我正在编写一个虚拟机,目前正在使用链表实现其内存。我已经实现了malloc,它向列表中添加了一个新节点,自由标记了一个节点,由malloc重用,现在我正在realloc上工作。我所遇到的问题是,由于有两个可变引用,我无法在链表的两个节点之间复制数据,这是一个最小的例子:

use std::collections::LinkedList;
struct MemoryBlock {
address: u64,
size: u64,
data: Vec<u8>
}
struct Memory {
blocks: LinkedList<MemoryBlock>,
}
impl Memory {
fn malloc(&mut self, alloc_size: u64) -> u64 {
self.blocks.push_back(MemoryBlock {
address: 1,
size: alloc_size,
data: vec![0x00]
});

1
}
fn realloc(&mut self, address: u64, new_size: u64) -> u64 {
let new_address = self.malloc(new_size);

let mut old_block = self.blocks.iter_mut().find(|b| b.address == address).unwrap();
let mut new_block = self.blocks.iter_mut().find(|b| b.address == new_address).unwrap();

new_block.data[0] = old_block.data[0];

new_address
}
}
fn main() {
let mut memory = Memory {
blocks: LinkedList::new()
};

memory.blocks.push_back(MemoryBlock {
address: 0,
size: 1,
data: vec![0x00]
});

memory.realloc(0, 2);
}

我试图使'old_block'不可变,但我不能同时有一个可变和一个不可变的借用。是否有任何方式来结构我的代码不同或任何其他方法(除了不安全),让它的工作?我知道我可以使用向量,然后使用切片作为"hack"来完成它,但如果可能的话,我更喜欢使用链表。

您可以重构代码,以便Rust编译器知道old_blocknew_block指向不同的位置。这也将更有效,因为LinkedList只遍历一次。

fn realloc(&mut self, address: u64, new_size: u64) -> u64 {
let new_address = self.malloc(new_size);
let mut old_block = None;
let mut new_block = None;
for block in &mut self.blocks {
if block.address == address {
old_block = Some(block);
} else if block.address == new_address {
new_block = Some(block);
}
}
new_block.unwrap().data[0] = old_block.unwrap().data[0];
new_address
}

游乐场

最新更新