0

ここはただの初心者。

ベクトル内にいくつかのオブジェクトを格納しようとしているので、後でループできますが、後で参照が変更され、何が起こったのかわかりません

コードは以下です。

#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;
}
4

3 に答える 3

4
  vector<Car*> vCar;

Carオブジェクトへのポインタを格納するベクトルです。

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

   garage.vCar.push_back(&car);
}

上記のforループ内で、Carスタックにオブジェクトを作成します。for ループの終わりまでに、これらのオブジェクトは範囲外になり、破棄されます。したがって、ベクトル内のポインターは、存在しないいくつかのオブジェクトを指しています。コードに未定義の動作があります。

オブジェクトを直接保存すると、元のオブジェクトのコピーが保存されます。ここでライブデモを見つけることができます。

于 2013-06-28T03:42:52.313 に答える
3

スタックベースのオブジェクトのアドレスをベクターにプッシュしていますが、そのスタックベースのオブジェクトは、スコープ外になるとすぐに破棄されます (for ループの反復が完了するとすぐに)。後でポインターを逆参照すると、実際には、最後のオブジェクトが作成されたスタック上のアドレスから読み取られます。これが、毎回同じ値を取得する理由です。

これを修正する方法はあなた次第です。オブジェクトCarへのポインターではなくオブジェクトを格納するようにベクトルを変更しCarたり、スマートポインターを使用したりできます.

于 2013-06-28T03:42:01.077 に答える
0

変化する

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

};

class Garage {
    public:
        vector<Car> vCar;

};

garage.vCar.push_back(&car);

garage.vCar.push_back(car);

これにより、発生している未定義の動作が解消されます (アイテムのアドレスがスタックから取り出されます!)。

于 2013-06-28T03:47:40.640 に答える