C ++, какая часть вектора копируется при передаче в функцию - PullRequest
0 голосов
/ 02 сентября 2018

я получил следующий прототип

void Foo(const vector<uint8_t> vec);

Теперь у меня сложилось впечатление, что в стек функций копируется только указатель на первый элемент в куче. Однако пока я перебираю свой код, я уже не уверен в этом. Прежде чем войти в Foo, мне нужно пройти через множество новых операторов []

Возможно ли, что весь вектор (то есть все элементы этого вектора) также будет скопирован?

Если да, то же самое относится и к спискам?

 void Foo(const List<uint8_t> ls);

Копируется ли весь список?

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Да, когда вы передаете значение, копируются фактические элементы, а не указатели.

См. Пример в ссылке ниже:

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; Стандарт: С ++ 11; Оптимизация: 0

Я не использовал оптимизацию только для того, чтобы заставить компилятор генерировать код, в котором он фактически создает новый вектор.

Скопируйте вышеуказанную программу в проводник компилятора, чтобы увидеть полный сгенерированный код сборки. Проводник компилятора

0 голосов
/ 02 сентября 2018

Конечно, копирование аргумента означает, что копируется весь вектор.

Если вы хотите получить ссылку, вы можете просто использовать:
void Foo(const vector<uint8_t>& vec);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...