Is vector::push_back() making a shallow copy & how to solve this

zw324 picture zw324 · Jul 16, 2011 · Viewed 7k times · Source

In the program I am writing, I have something similar to the code here:

#include<iostream>
#include<vector>
#include<cstring>

using namespace std;

struct people
{
    string name;
    int st;
    int sn[50];
};

int main()
{
    unsigned int n,ST[10]={25,18,15,12,10,8,6,4,2,1};
    vector<people> master;
    cin>>n;
    for (int i=0;i<n;i++)
    {
        unsigned int m;
        cin>>m;
        for (int j=0;j<m;j++)
        {
            people youngling; //I am declaring it here, but it doesn't solve the issue
            string s;
            cin>>s;
            for (int l=0;l<master.size();l++)
            {
                if (master[l].name.compare(s)==0)
                {
                    if (j<10) master[l].st+=ST[j];
                    master[l].sn[j]++;
                    goto loop;
                }
            }
            youngling.name=s;
            if (j<10) youngling.st=ST[j];
            for (int l=0;l<50;l++) youngling.sn[l]=0;
            youngling.sn[j]++;
            master.push_back(youngling);
            loop:;
        }
    }
}

As you can see, I am pushing back a struct (people youngling) into a vector (vector<people> master). However, this code is giving me the wrong results, and I think it might be caused by the struct and the shallow copy issue. This is proved somewhat since if I use a full array of people to store the input then the answer is correct. But I am puzzled by this:

  1. Is struct just a pointer to the compiler, or why does this shallow copy issue exist?
  2. I am declaring the people youngling inside the inner loop, hoping to solve this issue, but no use. Is there any easy way to correct the code snippet above?
  3. When I am testing on small cases using GCC 4.4, the answer seem to be right. However, when I test it use gnu C++0X, the answer is wrong. Is this a compiler-specific issue?

Note: I cannot provide the wrong test case since I am testing it online using a judge system.

Answer

Xion picture Xion · Jul 16, 2011

push_back is making the copy of object being inserted using its copy constructor. If there is no custom one (like in case of your struct), the default is just to copy all fields, using their own copy constructors, etc.

For your struct - containing a string and a fixed-size array of fundamental type - result should be equivalent to deep copy.