Joc*_*lyn 5 memory vector rust
我正在尝试将a 的内容复制Vec到现有的 中Vec,替换 target 的内容Vec。
这是我正在寻找的:
Vec太短),因为目标Vec已经分配Vec不应更改来源这是我尝试过的:
vec.clone():给出正确的内容,但分配新的内存,这对于复制到已经存在的足够大的内存中来说是不需要的Vecvec.clear(); vec.extend();:就地复制,但似乎在每个元素上使用迭代器,这不需要,我只想要一个 memcopyvec.copy_from_slice():是我正在寻找的,但需要完全相同大小的缓冲区,由于某种原因我似乎无法得到#![feature(shrink_to)]
fn vec_copy(src: &Vec<i32>, dst: &mut Vec<i32>) {
// Try to adjust dst buffer size... there should be a better way
if src.len() > dst.len() {
let addon = src.len() - dst.len();
dst.reserve_exact(addon);
} else {
dst.shrink_to(src.len());
}
// Do the copy
// panics! :
// thread 'main' panicked at libcore/slice/mod.rs:1645:9
// 'destination and source slices have different lengths'
//
dst.copy_from_slice(src.as_slice()); // <--- panics here
}
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]
}
Run Code Online (Sandbox Code Playgroud)
出现错误时出现恐慌:
#![feature(shrink_to)]
fn vec_copy(src: &Vec<i32>, dst: &mut Vec<i32>) {
// Try to adjust dst buffer size... there should be a better way
if src.len() > dst.len() {
let addon = src.len() - dst.len();
dst.reserve_exact(addon);
} else {
dst.shrink_to(src.len());
}
// Do the copy
// panics! :
// thread 'main' panicked at libcore/slice/mod.rs:1645:9
// 'destination and source slices have different lengths'
//
dst.copy_from_slice(src.as_slice()); // <--- panics here
}
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]
}
Run Code Online (Sandbox Code Playgroud)
usingvec.copy_from_slice()似乎是将 a 的内容内存复制到Vec另一个中的方法,无需不必要的内存分配,也无需使用迭代器。
如何设置目标的大小Vec以免vec.copy_from_slice()出现恐慌?
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);
}
Run Code Online (Sandbox Code Playgroud)
这避免了在添加比先前分配的元素更多的元素时需要用“虚拟值”填充向量。
如果您在发布模式下查看程序集,它会memcpy在确定有足够的分配空间后调用:
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
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)println!("{:p} = {:?}", &container[0], container);
container.as_ptr()比向量为空时更明显&container[0]并且不会失败。
也可以看看:
| 归档时间: |
|
| 查看次数: |
3186 次 |
| 最近记录: |