badcoder
badcoder

Reputation: 301

inconsistent object IDs inside multiple vector in C++

just a beginner here.

i'm trying to store some objects inside a vector, so i can loop it later, but the reference changes afterwards, i'm not sure what happened

the code's below;

#include <iostream>
#include <vector>

using namespace std;

class Car;

class Garage {
    public:
        vector<Car*> vCar;

};

class Car {
    public:
        short id;
};

int main()
{
   Garage garage;
   short i;

   for(i = 0; i < 10; i++) {
       Car car;
       car.id = i;

       garage.vCar.push_back(&car);
   }

   for(i = 0; i < garage.vCar.size(); i++) {
       cout <<  i << " " << garage.vCar[i]->id << endl;
       // output 9,9,9,..9 instead of 1,2,3,4...10, why is that?
   }


   return 0;
}

Upvotes: 0

Views: 66

Answers (3)

Ed Heal
Ed Heal

Reputation: 60047

Change

class Garage {
    public:
        vector<Car*> vCar;

};

To

class Garage {
    public:
        vector<Car> vCar;

};

And

garage.vCar.push_back(&car);

To

garage.vCar.push_back(car);

This will eliminate the undefined behaviour that you are experiencing ( you are taking an address of an item off the stack!)

Upvotes: 0

taocp
taocp

Reputation: 23664

  vector<Car*> vCar;

is a vector that stores pointers to Car objects.

 for(i = 0; i < 10; i++) {
   Car car;
   car.id = i;

   garage.vCar.push_back(&car);
}

Inside the above for loop, you create Car objects on stack. By the end of the for loop, those objects are out of scope and will be destroyed. Therefore, your pointers inside the vector point to some objects that do not exist. You have undefined behavior in your code.

You may store objects directly, which stores copy of the original objects. You can find a Live Demo here.

Upvotes: 4

Jonathan Potter
Jonathan Potter

Reputation: 37202

You're pushing the address of a stack-based object into the vector, but that stack based object will be destroyed as soon as it goes out of scope (so as soon as the iteration of the for-loop is complete). When you dereference the pointer later on you're actually reading from the address on the stack where the last object was created, which is why you get the same value every time.

How you fix this is up to you - you could change the vector to store Car objects rather than pointers to Car objects, you could use smart pointers, etc..

Upvotes: 3

Related Questions