1

I am reading from a file and with the information that I receive I want to parse the data and store them into their respectful objects which will then be pushed back into a vector. However, when the code stores the information into the object and is then pushed back into the vector, the vector does not hold that value. It then skips a few places within the vector and begins to add the objects correctly towards the end of the file. Is there a way to make sure all elements will be filled?

Here are my Structs:

struct Address{ 
        string streetAddress; 
        string city; 
        string state; 
        string zipCode; 
};

struct Customer { 
        string customerNum; 
        string customerName; 
        double lineOfCredit; 
        Address * corperateAddress; 
};

As you can see the member of Customer is a pointer that points to the Address struct.

Here is the function and some variables being used for the code below:

void readData(vector<Customer>&addCust, vector<Address>&cAdd, vector<Product>&pAdd){

Address street;
Customer add;
Product product;

vector<string> custInfo;
vector<string> custAddress;
vector<string> custProduct;
ifstream file,stock;

This is where the error occurs I believe it is within the if-else statement:

        custAddress=parse(location,',');                   //Parse the location to go into Address struct
        check = linearSearchAddress(cAdd,custAddress[0]);  //Checks Address vector to see if there is the same location

        street.streetAddress=custAddress[0];               //Adds 1st parse to the Struct member 
        street.city=custAddress[1];                        //Adds 2nd parse to the Struct member 
        street.state=custAddress[2];                       //Adds 3rd parse to the Struct member 
        street.zipCode=custAddress[3];                     //Adds 4th parse to the Struct member

        if(check==-1){                                     //If address is not found then add it to the Address vector 
            cAdd.push_back(street);                        //Adding objects into the Address vector
            add.corperateAddress = &cAdd.back();
        } else {
            add.corperateAddress=&cAdd[check];             //Adds location that is within vector already 
        }
         addCust.push_back(add);                           //Adding objects into Customer vector
     }
        cout<<addCust[0].corperateAddress->streetAddress<<endl;  // Element is empty some how ?

1 Answers1

3

When you call push_back on a vector, if it causes the vector to increase in size, it invalidates all pointers and references into the vector. A vector stores all objects in one contiguous block of memory, so when it increases in size it may need to allocate a new block of memory, causing all existing objects in the vector to be moved into that new location.

Your pattern of storing pointers to objects in a vector is not a good one, though you can make it work by reserving sufficient space in the vector from the beginning -- if you know how big it will be. Otherwise, you can use some collection other than a vector that doesn't have this property.

David Schwartz
  • 166,415
  • 16
  • 184
  • 259
  • [Some reading to help select a different container](https://stackoverflow.com/questions/6438086/iterator-invalidation-rules), should you choose to go that way. – user4581301 Apr 08 '19 at 04:38