1

When I push_back() 3 items into a vector, the copy constructor is triggered 6 times. I can't understand the logic behind this, can you help?

struct vertex{
    float x, y, z;

    vertex(float x, float y, float z) : x(x), y(y), z(z){

    }

    vertex(const vertex& other) : x(other.x), y(other.y), z(other.z){
        std::cout << "copied" << std::endl;
    }
};


int main(){
    std::vector<vertex> vertices;

    vertices.push_back(vertex(1, 2, 3));
    vertices.push_back(vertex(4, 5, 6));
    vertices.push_back(vertex(7, 8, 9));
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
maiev
  • 11
  • 1
  • You should log the value of the `this` pointer in both constructors, and in the destructor, and also the address of `other` in the copy constructor, then you will see which objects are being created/destroyed and which objects are being copied – Remy Lebeau Jul 06 '22 at 19:32
  • It may help to see what is being copied: https://godbolt.org/z/boKoM6x78 Here you can see the the copies from the resizing. – user4581301 Jul 06 '22 at 19:33

1 Answers1

3

A copy is made for each temporary object you are pushing. Also, if the vector has to reallocate its inner array, existing elements that can't be moved to the new memory will instead be copied to the new memory.

You can avoid all of these copies by reserve()'ing the vector up front, and using emplace_back() instead of push_back().

struct vertex{
    float x, y, z;

    vertex(float x, float y, float z) : x(x), y(y), z(z){

    }

    vertex(const vertex& other) : x(other.x), y(other.y), z(other.z){
        std::cout << "copied" << std::endl;
    }
};


int main(){
    std::vector<vertex> vertices;
    vertices.reserve(3);

    vertices.emplace_back(1, 2, 3);
    vertices.emplace_back(4, 5, 6);
    vertices.emplace_back(7, 8, 9);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770