Vivek Kumar
Vivek Kumar

Reputation: 5040

efficient push_back in std::vector

In the code below there is 3 object of d1 and d2 gets created for doing push_back(). One when I have created, one in calling v.push_back() and another when it is actually copied into the vector {of which I am not sure}.

What will be best alternative to avoid this without using std::vector in C++03?

#include <iostream>
#include <vector>
#include <string>

using namespace std;

struct Details
{
    string fname;
    string lname;
    string address;
    int age;
};

int main(int argc, char **argv)
{
    vector<Details> v;

    Details d1;
    d1.fname = "vivek";
    d1.lname = "kumar";
    d1.address = "New Delhi";
    d1.age = 25;

    v.push_back(d1);

    Details d2;
    d2.fname = "some name";
    d2.lname = "some lastname";
    d2.address = "some address";
    d2.age = 25;

    v.push_back(d2);

    return 0;
}

Upvotes: 2

Views: 3681

Answers (2)

Oswald
Oswald

Reputation: 31665

Calling std::vector::push_back() does not create a copy per se, because a const reference is passed. It only creates the copy that becomes the vector element. And this copy is required by the semantics of std::vector.

You could also push_back() the Details at a time when copying is relatively cheap:

Details d1; // Now the 3 strings of d1 are still small
v.push_back(d1); // essentially copies 3 empty strings and an int.
v.back().fname = "vivek";
v.back().lname = "kumar";
v.back().address = "New Delhi";
v.back().age = 25;

Upvotes: 6

Ed Barbu
Ed Barbu

Reputation: 1639

If you really have determined that performance is of paramount importance here then you are going to need/implement reference semantics.

  • In C++11 you have move semantics, so you would implement a move constructor for the Details structure, so I would normally strongly suggest using that
  • Since you are using C++03, you can use boost::shared_ptr to wrap your Details structure in, like this: vector<boost::shared_ptr<Details> >. Since you are using C++03 please mind the space character between >.
  • normally I would recommend unique_ptr instead of shared_ptr, but unique_ptr is only available in C++11, where the move semantics alternative is better most of the time.
  • the reason I'm not recommending raw pointers is because you need to manually manage memory for them, which is a no-no.

As for your example, please note that in C++03 push_back takes a const reference, so there's only one copy of your structure involved. Using any of the methods I suggested above will still do one copy, but the size of the copy will be kept in check and won't scale with the size of your structure, which might be exactly what you want when you are working with large data.

Upvotes: 1

Related Questions