在链表节点之间复制数据
Copying data between linked list nodes
我正在编写一个虚拟机,目前正在处理使用链表实现的内存。我已经实现了 malloc,它将一个新节点添加到列表中,free 标记了一个节点将被 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_block
和 new_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
}
我正在编写一个虚拟机,目前正在处理使用链表实现的内存。我已经实现了 malloc,它将一个新节点添加到列表中,free 标记了一个节点将被 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_block
和 new_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
}