3

If I have created a vector object, an instance that has a size of 24 Bytes (on my machine) will be allocated. I have read that a vector object contains (roughly speaking) two elements:

  1. Pointer points to the first element of the data stored in the heap memory.
  2. The size of the data.

I know that passing by value will not affect the original data, let's say that we have passed (by value) a vector of characters to a function, and the above two elements will be copied (the pointer and the size), so the copied pointer (in the copied vector object) will still point to the same data that the original pointers (in the original vector object) point to.

my question is if the copied pointer still points to the same data (please correct me if I am wrong) why does change the copied vector data doesn't affect the original vector (both vectors are copied and so are the pointers inside them)?

Illustrating my thought

#include <iostream>
#include <vector>

using namespace std;

void printVector(vector<char> vec) {
    for (char c: vec) 
        cout << c << " ";
    cout << endl;
}

void changeVector(vector<char> copiedVector) {
    copiedVector.at(0) = 'x';
    copiedVector.at(1) = 'y';
    copiedVector.at(2) = 'z';
    
    printVector(copiedVector);
}

int main() {
    vector<char> originalVector {'a', 'b', 'c'};
    
    cout << "The original vector contains: ";
    printVector(originalVector);
    cout << endl;
    
    cout << "The copied vector contains: ";
    changeVector(originalVector);
    cout << endl;
    
    cout << "The original vector (after calling changeVector function) contains: ";
    printVector(originalVector);
    cout << endl;

    return 0;
}

The Output:

The original vector contains: a b c

The copied vector contains: x y z

The original vector (after calling changeVector function) contains: a b c

Sorry for posting stupid questions, I tried to do a lot of searching but I didn't get the answers that I was looking for.

I am new to C++, so please be gentle and explain this to me in a simple and detailed way so I can correct myself.

Thanks in advance.

  • 1
    The value parameter contains a deep copy of your original, can you elaborate about your concern please? – πάντα ῥεῖ Aug 25 '22 at 18:47
  • 5
    Copying a `std::vector` does a deep copy of the vector and the elements it owns. – Richard Critten Aug 25 '22 at 18:47
  • 2
    This is incorrect. When a `std::vector` gets copied, the underlying data gets copied as well. – Sam Varshavchik Aug 25 '22 at 18:47
  • your analysis of the vector memory implementation is correct. So the behaviour could have been that a copy of the vector does not duplicate its contents, however thats not what the vector design does, it does a deep copy – pm100 Aug 25 '22 at 18:49
  • 1
    Each `std::vector` [owns](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) its data and implements the [Rule of Five](https://en.cppreference.com/w/cpp/language/rule_of_three) to maintain and transfer ownership. – user4581301 Aug 25 '22 at 18:54
  • 1
    Does this answer your question? [What is a copy constructor in C++?](https://stackoverflow.com/questions/2168201/what-is-a-copy-constructor-in-c) – Karl Knechtel Aug 25 '22 at 18:54
  • @KarlKnechtel yes this helped me, thank you guys for explaining this to me, I didn't know that there is a thing called copy constructor, all I was thinking pass by value is just copying the same bytes to a different memory location. – Osama Alkurdi Aug 25 '22 at 19:20

1 Answers1

2

When we say that an object is copied in C++, we do not mean that the bytes of the storage that the object occupies are simply copied as if by memcpy which is what you are describing.

Instead copying means invoking the copy constructor (or the copy assignment operator) of the class type to perform the copy operation in a way that makes sense for the type. The copy constructor of std::vector performs a deep copy, allocating new memory to store copies of each element of the original vector and the internal pointer of the new vector will be set to point to this newly allocated memory.

In the call changeVector(originalVector); the argument is an lvalue of type std::vector<char> and the parameter of the function is a (non-reference) std::vector<char>. When the function is called the parameter is copy-initialized from the argument. Because std::vector<char> is a class type that means the compiler will look for a (non-explicit) constructor in std::vector<char> which accepts exactly one lvalue argument of type non-const std::vector<char>. The copy constructor has the signature

vector(const vector&)

and is therefore a valid choice for this and will be chosen to construct the std::vector<char> in the parameter.

(The compiler will also consider conversion functions in the argument's type to initialize the parameter, but that is not relevant here.)

user17732522
  • 53,019
  • 2
  • 56
  • 105