我得到了以下原型
void Foo(const vector<uint8_t> vec);
现在我的印象是,只有指向堆上第一个元素的指针才被复制到函数堆栈中。但是,在单步执行代码时,我不确定。在实际进入Foo之前,我必须经历很多new []运算符
是否也可以复制整个向量(即该向量的所有元素)?
如果是的话,同样的事情也适用于列表吗?
void Foo(const List<uint8_t> ls);
是否也复制了整个列表?
答案 0 :(得分:3)
当然,参数复制意味着整个矢量都会被复制。
您希望移交参考,可以简单使用:
void Foo(const vector<uint8_t>& vec);
答案 1 :(得分:1)
是的,当您按值传递时,将复制实际的元素,而不是指针。
请参见以下链接中的示例:
#include <vector>
#include <cstdint>
#include <iostream>
void copy_all_elements(std::vector<uint8_t> vec_copy)
{
vec_copy.push_back(70);
std::cout<<"In copy_all_elements: ";
for (auto i : vec_copy)
std::cout<<(unsigned)i<<"\t";
std::cout<<"\n";
}
int main()
{
std::vector<uint8_t> vec{10,20,30,40,50};
copy_all_elements(vec);
vec.push_back(60);
std::cout<<"In Main: ";
for (auto i : vec)
std::cout<<(unsigned)i<<"\t";
std::cout<<"\n";
}
答案:
In copy_all_elements: 10 20 30 40 50 70
In Main: 10 20 30 40 50 60
如您所见,这两个向量是不同的,因为如果副本仅复制了指针,则将元素插入一个向量应该反映在另一个向量中,而这在这里没有发生。
如果您想查看编译器的确切功能,则可以生成汇编代码并进行检查。
lea rdx, [rbp-112]
lea rax, [rbp-80]
mov rsi, rdx
mov rdi, rax
call std::vector<unsigned char, std::allocator<unsigned char> >::vector(std::vector<unsigned char, std::allocator<unsigned char> > const&)
lea rax, [rbp-80]
mov rdi, rax
call copy_all_elements(std::vector<unsigned char, std::allocator<unsigned char> >)
lea rax, [rbp-80]
mov rdi, rax
call std::vector<unsigned char, std::allocator<unsigned char> >::~vector() [complete object destructor]
编译器:x86-64 gcc 8.2; 标准:C ++ 11; 优化:0
我并没有使用优化来强迫编译器在实际创建新矢量的地方生成代码。
请将以上程序复制到编译器资源管理器中,以查看生成的compiler explorer完整的汇编代码