Different ways to copy a vector in C++


Reading time: 30 minutes | Coding time: 5 minutes

An array has a fixed size when it is declared. But if we want a dynamic array whose size can vary at runtime then we use vector. Elements are inserted in vector from end using push_back(). Like arrays, elements in vector are also stored contiguously and they can traversed using iterators. Iterators return pointers to elements.

In this article, we will explore different methods to copy a vector in C++ and all covered methods use deep copy that the memory address of new copy is different from the original vector.

Ways of copying a vector into other

1. Iterative method :-

In this method a loop runs over the old vector and elements are inserted in new vector using push_back().This function inserts elements in vector from back.

    // C++ code to demonstrate copy of vector using iterative method
    #include<iostream> 
    #include<vector> //to include vector container in code
    using namespace std; 

    int main() 
    { 
        // Initializing vector with values 
        vector<int> v1;
        int num;
        for(int i=0;i<4;i++)
        {
            cin>>num;
            v1.push_back(num);// adding elements to vector v1
        }

        // Declaring new vector 
        vector<int> v2; 

        // A loop to copy elements of old vector into new vector 
        //by Iterative method 
        for (int i=0; i<v1.size(); i++) 
            v2.push_back(v1[i]); 

        cout << "Old vector elements are : "; 
        for (int i=0; i<v1.size(); i++) 
            cout << v1[i] << " "; 
        cout << endl; 

        cout << "New vector elements are : "; 
        for (int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 
        cout<< endl; 

        return 0; 
    } 

Output :- (If inputs are 10,20,30,40)

Old vector elements are : 10 20 30 40
New vector elements are : 10 20 30 40

Complexity :- As the loop traverses all the elements once so complexity is O(n) where n is number of elements in old vector.

2. Assignment operator(=) :-

In this method elements from old vector are inserted into new vector by assigning new vector to old vector. This does not happen in arrays.

    // C++ code to demonstrate copy of vector by '=' operator. 
    #include<iostream> 
    #include<vector> //to include vector container in code
    using namespace std; 

    int main() 
    { 
        // Initializing vector with values 
        vector<int> v1;
        int num;
        for(int i=0;i<4;i++)
        {
            cin>>num;
            v1.push_back(num);// adding elements to vector v1
        }

        // Declaring new vector 
        vector<int> v2; 

        // Using assignment operator to copy one vector to other 
        v2 = v1; 

        cout << "Old vector elements are : "; 
        for (int i=0; i<v1.size(); i++) 
            cout << v1[i] << " "; 
        cout << endl; 

        cout << "New vector elements are : "; 
        for (int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 
        cout<< endl;

        return 0; 
    } 

Output :- (If inputs are 1,2,3,4)
Old vector elements are : 1 2 3 4
New vector elements are : 1 2 3 4

Complexity :- Linear time complexity as elements have to traversed once to assign them to new vector.

3. Passing vector as constructor :-

At the time of declaration of vector, passing old vector as an argument of constructor, copies the elements of passed vector into the newly declared vector.

    // C++ code to demonstrate copy of vector by constructor method. 
    #include<iostream> 
    #include<vector> //to include vector container in code
    using namespace std; 

    int main() 
    { 
        // Initializing vector with values without taking inputs from user
        vector<int> v1{1, 2, 3, 4}; 

        // Declaring new vector and passing old vector as argument to constructor 
        vector<int> v2(v1); 

        cout << "Old vector elements are : "; 
        for (int i=0; i<v1.size(); i++) 
            cout << v1[i] << " "; 
        cout << endl; 

        cout << "New vector elements are : "; 
        for (int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 
        cout<< endl;

        return 0; 
    } 

Output :-
Old vector elements are : 1 2 3 4
New vector elements are : 1 2 3 4

Complexity :-
O(n) as elements are traversed once when old vector is passed as argument to constructor.

4. Using inbuild functions :-

  • copy(first_iterator, last_iterator, back_inserter()) :-
copy(first_iterator, last_iterator, back_inserter())

This function takes 3 arguments, the first iterator of old vector, the last iterator of old vector and third is back_inserter function to insert values from back. We can also pass first iterator + number of elements in place of last iterator and last iterator of new vector in place of back_inserter() if we want to copy a certain portion of elements starting from first element of old vector.

    // C++ code to demonstrate copy of vector by copy(). 
    #include<iostream> 
    #include<vector> // to include vector container in code 
    #include<algorithm> // for copy()
    #include<iterator> // for back_inserter 
    using namespace std; 
    int main() 
    { 
        // Initializing vector with values 
        vector<int> v1{1, 2, 3, 4}; 

        // Declaring new vector 
        vector<int> v2; 
        vector<int> v3(4); //vector of size 4

        // Copying vector by copy function 
        // begin() returns pointer to first element, end() returns
        // pointer to last element
        copy(v1.begin(), v1.end(), back_inserter(v2)); 

        // using copy() to copy 1st 3 elements and other empty indexes are filled with 0
       copy(v1.begin(), v1.begin()+3, v3.begin()); 

        cout << "Old vector elements are : "; 
        for (int i=0; i<v1.size(); i++) 
            cout << v1[i] << " "; 
        cout << endl; 

        cout << "New vector elements of v2 are : "; 
        for (int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 
        cout<< endl;

        cout << "New vector elements of v3 are : "; 
        for (int i=0; i<v3.size(); i++) 
            cout << v3[i] << " "; 
        cout<< endl;

        return 0; 
    } 

Output :-
Old vector elements are : 1 2 3 4
New vector elements of v2 are : 1 2 3 4
New vector elements of v3 are : 1 2 3 0

Complexity :- O(n) as copy() takes linear time to traverse elements. But begin(),end() and back_inserter() takes constant time.

  • assign(first_iterator, last_iterator) :-
assign(first_iterator, last_iterator)

This function takes 2 arguments, first iterator to old vector and last iterator to old vector. It then assigns values of old vector to new vector.

    // C++ code to demonstrate copy of vecto by assign() 
    #include<iostream> 
    #include<vector> // to include vector container in code 
    #include<algorithm> // for assign()
    using namespace std; 

    int main() 
    { 
        // Initializing vector with values 
        vector<int> v1{1, 2, 3, 4}; 

        // Declaring another vector 
        vector<int> v2; 

        // Copying vector by assign function 
        //begin() returns pointer to first element, end() returns
        // pointer to last element
        v2.assign(v1.begin(), v1.end()); 

        cout << "Old vector elements are : "; 
        for (int i=0; i<v1.size(); i++) 
            cout << v1[i] << " "; 
        cout << endl; 

        cout << "New vector elements are : "; 
        for (int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 
        cout<< endl; 

        return 0; 
    } 

Output :-
Old vector elements are : 1 2 3 4
New vector elements are : 1 2 3 4

Complexity :-
O(n) as assign() takes O(n) time where n is the number of elements in old vector.

Apart from these there are more methods in C++ STL(Standard Template Library) which allows copying of vectors in different manners. They are :-

  1. copy_n(iterator_source, num, iterator_dest) :
copy_n(iterator_source, num, iterator_dest)

By using this method we can choose how many elements have to be copied to new vector. It takes 3 arguments :-

iterator_source : The pointer to the beginning of source vector, from where elements have to be started copying.
num : Integer specifying how many numbers would be copied to destination vector starting from iterator_source. If a negative number is entered, no operation is performed.
iterator_dest : The pointer to the beginning of destination vector, to where elements have to be started copying.

    // C++ code to demonstrate the working of copy_n() 

    #include<iostream> 
    #include<algorithm> // for copy_n() 
    #include<vector> // to include vector container in code  
    using namespace std; 

    int main() 
    { 

       // intializing source vector  
       vector<int> v1 = { 1, 2, 3, 4, 5, 6 }; 

       // declaring destination vectors 
       vector<int> v2(6); //vector of size 6

       // using copy_n() to copy 1st 4 elements and other elements will be filled by 0
       copy_n(v1.begin(), 4, v2.begin()); 

       // printing new vector 
       cout << "The new vector elements entered using copy_n() : "; 
       for(int i=0; i<v2.size(); i++) 
       cout << v2[i] << " "; 

       return 0;
    } 

Output :-
The new vector elements entered using copy_n() : 1 2 3 4 0 0

Complexity :-
Best case of O(1) if no traversal is required.
Worst case of O(n) if all elements from old vector are copied to new vector.

  1. copy_if() : This function copies elements according to result of a “condition“ which is provided with the help of a 4th argument, a function returning a boolean value.
    This function takes 4 arguments, 3 of them similar to copy() and additional function, which when returns true, a number is copied, else number is not copied.

  2. copy_backwards() : This function starts copying elements into the destination vector from backwards and keeps on copying till all numbers are not copied. The copying starts from the “iterator_dest” but in backward direction. It also takes similar arguments as copy().

    // C++ code to demonstrate the working of copy_if() and                       //copy_backward()

    #include<iostream> 
    #include<algorithm> // for copy_if() and copy_backward() 
    #include<vector> // to include vector container in code 
    using namespace std;

    int main() 
    { 

        // intializing source vector  
        vector<int> v1 = { 1, 2, 3, 4, 5, 6 }; 

        // declaring destination vectors 
        vector<int> v2(6); // vector of size 6
        vector<int> v3(6); // vector of size 6

        // using copy_if() to copy odd elements 
        // condition is given as an argument
        copy_if(v1.begin(), v1.end(), v2.begin(), [](int i){returni%2!=0;}); 

        // printing new vector 
        cout << "The new vector elements entered using copy_if() : "; 
        for(int i=0; i<v2.size(); i++) 
            cout << v2[i] << " "; 

        cout << endl; 

        // using copy_backward() to copy 1st 4 elements of old vector
        // starting at second last position(as it is v3.begin() + 5) and copying backwards from old vector
        copy_backward(v1.begin(), v1.begin() + 4, v3.begin()+ 5); 

        // printing new vector 
        cout << "The new vector elements entered using copy_backward():"; 
        for(int i=0; i<v3.size(); i++) 
            cout << v3[i] << " "; 

        return 0;

    } 

Output :-
The new vector elements entered using copy_if() : 1 3 5 0 0 0
The new vector elements entered using copy_backward() : 0 1 2 3 4 0

Complexity :-
Best case of O(1) if no traversal required.
Worst case of O(n) as in case of copy() function.

All the ways discussed above implements deep copy which means the location address of old and new vector are different. So, when values of old vector are changed, it does not reflect in new vector.

Question

copy_if() takes how many arguments?

4
3
2
1

It is same as copy() and one extra argument is for the function returning boolean value according to condition