Memory 试图将一个Vec的内容复制到另一个Vec中,如何使用copy_from_slice()?
我试图将Memory 试图将一个Vec的内容复制到另一个Vec中,如何使用copy_from_slice()?,memory,vector,rust,Memory,Vector,Rust,我试图将Vec的内容复制到现有Vec中,替换目标Vec的内容 以下是我想要的: 不需要分配新内存(除非目标Vec太短),因为目标Vec已分配 它不应该使用迭代器,因为memcopy应该足以完成这项工作 不应更改源Vec 理想情况下,它应该使用安全的方法 以下是我尝试过的: vec.clone() vec.clear();vec.extend():复制到位,但似乎在每个元素上都使用了迭代器,这是不需要的,我只需要一个memcopy vec.copy\u from\u slice():是我正在
Vec
的内容复制到现有Vec
中,替换目标Vec
的内容
以下是我想要的:
- 不需要分配新内存(除非目标
太短),因为目标Vec
已分配Vec
- 它不应该使用迭代器,因为memcopy应该足以完成这项工作
- 不应更改源
Vec
- 理想情况下,它应该使用安全的方法
vec.clone()
vec.clear();vec.extend()代码>:复制到位,但似乎在每个元素上都使用了迭代器,这是不需要的,我只需要一个memcopy
:是我正在寻找的,但需要完全相同大小的缓冲区,由于某种原因,我似乎无法获得vec.copy\u from\u slice()
vec.copy\u from_slice()
似乎是将vec
的内容就地memcopy到另一个的方法,无需不必要的内存分配,也无需使用迭代器
如何设置目标Vec
的大小,以便Vec.copy\u from\u slice()
不会死机?您可以使用以下功能:
fn vec_copy(src: &Vec<i32>, dst: &mut Vec<i32>) {
dst.resize(src.len(), 0);
dst.copy_from_slice(src.as_slice());
}
fn main() {
// Copy from a shorter Vec
let mut container = vec![1, 2];
let test1 = vec![3]; // shorter vec
println!("{:p} = {:?}", &container[0], container); // output: 0x7f00bda20008 = [1, 2]
vec_copy(&test1, &mut container); // panics inside function
println!("{:p} = {:?}", &container[0], container); // expected: 0x7f00bda20008 = [3]
// Copy from a longer Vec
container = vec![1, 2];
let test2 = vec![4, 5, 6]; // longer Vec
println!("{:p} = {:?}", &container[0], container); // output: 0x7fef5b820018 = [1, 2]
vec_copy(&test2, &mut container); // panics inside function
println!("{:p} = {:?}", &container[0], container); // expected: 0x7fef5b820018 = [4, 5, 6]
}
最后一个有不同的地址,可能是因为目的地的容量比源地小,所以它必须增长,这意味着重新分配。这可以通过打印出目的地的容量,并观察其从2->4增长来显示:
println!("{:p} = {:?} (capacity: {:?})", &container[0], container, container.capacity());
vec_copy(&test2, &mut container); // panics inside function
println!("{:p} = {:?} (capacity: {:?})", &container[0], container, container.capacity());
输出:
0x7f2e36020008 = [1, 2]
0x7f2e36020008 = [3]
0x7f2e36020028 = [1, 2]
0x7f2e3602a010 = [4, 5, 6]
0x7f16a1820008 = [1, 2]
0x7f16a1820008 = [3]
0x7f16a1820028 = [1, 2] (capacity: 2)
0x7f16a182a010 = [4, 5, 6] (capacity: 4)
您可以通过确保目标在创建时足够大来防止这种情况。您需要:
container.as_ptr()
比&container[0]
更明显,并且当向量为空时不会失败
另见:
resize()
),并且它仍然在内部使用copy\u from\u slice()
。当然,不用担心,我理解并同意。很乐意帮忙!谢谢你的各种提示!我担心extend\u from\u slice()
会在循环中独立复制每个元素。我被以下状态弄糊涂了:“迭代切片,克隆每个元素,然后将其附加到这个Vec”。但它最终在内部调用了copy\u from_slice()
,并执行了一个独特的memcpy,这正是我想要的。在复制之前,它会执行一个reserve()
和set_len()
,这就是为什么我们可以在之前使用truncate()
。请注意,vec.truncate(0)
可以缩写为vec.clear()
。
0x7f16a1820008 = [1, 2]
0x7f16a1820008 = [3]
0x7f16a1820028 = [1, 2] (capacity: 2)
0x7f16a182a010 = [4, 5, 6] (capacity: 4)
fn vec_copy(src: &[i32], dst: &mut Vec<i32>) {
// Optionally truncate to zero if there might be existing data
// dst.clear();
dst.extend_from_slice(src);
}
playground::vec_copy:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $88, %rsp
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movq 8(%rbx), %rsi
movq 16(%rbx), %r12
movq %rsi, %rax
subq %r12, %rax
cmpq %r15, %rax
jae .LBB1_14
addq %r15, %r12
jb .LBB1_8
leaq (%rsi,%rsi), %rax
cmpq %rax, %r12
cmovbq %rax, %r12
movl $4, %ecx
movq %r12, %rax
mulq %rcx
jo .LBB1_8
testq %rsi, %rsi
je .LBB1_9
shlq $2, %rsi
movq (%rbx), %rdi
movq %rsp, %r9
movl $4, %edx
movl $4, %r8d
movq %rax, %rcx
callq __rust_realloc@PLT
testq %rax, %rax
jne .LBB1_5
movq (%rsp), %rax
jmp .LBB1_12
.LBB1_9:
movq %rsp, %rdx
movl $4, %esi
movq %rax, %rdi
callq __rust_alloc@PLT
testq %rax, %rax
je .LBB1_12
.LBB1_5:
xorl %ecx, %ecx
movdqa 32(%rsp), %xmm0
movdqa %xmm0, 48(%rsp)
testq %rcx, %rcx
je .LBB1_13
.LBB1_6:
movq %rax, (%rsp)
movaps 48(%rsp), %xmm0
movups %xmm0, 8(%rsp)
leaq 64(%rsp), %rdi
movq %rsp, %rsi
callq <core::heap::CollectionAllocErr as core::convert::From<core::heap::AllocErr>>::from@PLT
movdqa 64(%rsp), %xmm0
movq %xmm0, %rax
cmpq $3, %rax
je .LBB1_14
cmpq $2, %rax
jne .LBB1_15
.LBB1_8:
leaq .Lbyte_str.5(%rip), %rdi
callq core::panicking::panic@PLT
ud2
.LBB1_12:
movups 8(%rsp), %xmm0
movaps %xmm0, 32(%rsp)
movl $1, %ecx
movdqa 32(%rsp), %xmm0
movdqa %xmm0, 48(%rsp)
testq %rcx, %rcx
jne .LBB1_6
.LBB1_13:
movq %rax, (%rbx)
movq %r12, 8(%rbx)
.LBB1_14:
movq 16(%rbx), %rdi
leaq (%rdi,%r15), %rax
movq %rax, 16(%rbx)
shlq $2, %r15
shlq $2, %rdi
addq (%rbx), %rdi
movq %r14, %rsi
movq %r15, %rdx
callq memcpy@PLT
addq $88, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
.LBB1_15:
movq 80(%rsp), %rax
movdqa %xmm0, (%rsp)
movq %rax, 16(%rsp)
movq %rsp, %rdi
callq <alloc::heap::Heap as core::heap::Alloc>::oom
ud2
println!("{:p} = {:?}", &container[0], container);