C ++将向量的哪一部分传递给函数时将被复制

时间:2018-09-02 20:15:23

标签: c++ vector

我得到了以下原型

void Foo(const vector<uint8_t> vec);

现在我的印象是,只有指向堆上第一个元素的指针才被复制到函数堆栈中。但是,在单步执行代码时,我不确定。在实际进入Foo之前​​,我必须经历很多new []运算符

是否也可以复制整个向量(即该向量的所有元素)?

如果是的话,同样的事情也适用于列表吗?

 void Foo(const List<uint8_t> ls);

是否也复制了整个列表?

2 个答案:

答案 0 :(得分:3)

当然,参数复制意味着整个矢量都会被复制。

您希望移交参考,可以简单使用:
void Foo(const vector<uint8_t>& vec);

答案 1 :(得分:1)

是的,当您按值传递时,将复制实际的元素,而不是指针。

请参见以下链接中的示例:

copy_all_elements

#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完整的汇编代码