2016-07-01 7 views
1

printoutは、私が期待しているものとは多少異なります。コストとスピードを持つCarをベクトル[cars.push_back(Car(costs, speed))]にプッシュし、ローカルベクトルCar*car_vec.push_back(&cars.back())のthis Carへのポインタを押します。次に、キー(costs)と値(car_vec)をマップに挿入します。マップを印刷すると、値は正しくなりません。例えば、最初のケースでマップの挿入によってオブジェクトのメンバー値が変更されるのはなぜですか?

: 最初のループi = 0、インナーループj、従って(> = I j)及びIはCar(1000.0, 10.0)を一back。マップに含まれる内容は、後でCar(0,0)です。他の車でも同様ですが、いくつかの奇妙な値があります。

map[1000] = [0, 0] , [0, 7.41086e-38] , [0, 7.41063e-38] , [0, 7.41064e-38] , [210, 1700] , 

map[1700] = [0, 7.41092e-38] , [0, 7.41094e-38] , [0, 7.41094e-38] , [210, 1700] , 

map[2400] = [110, 2400] , [160, 2400] , [210, 2400] , 

map[3100] = [160, 3100] , [210, 3100] , 

map[3800] = [210, 3800] , 

私は何が起こっているのか分かりません。デバッグでは、car_storage.insert({costs , car_vec } )にマップに挿入されるまで、値は正常だったことがわかりました。

答えて

2

あなたはこの書き込み時に何が起こる:

cars.push_back(Car(costs, speed)) 
car_vec.push_back(&cars.back()) 

を? Carを作成し、コピーcarsベクターにプッシュします。次の行でポインタをこのベクトルのコピーにプッシュします。決してそれをしないでください!最初のベクトルのサイズがpush_backclearなどのように変更された場合は、すべてのコンテンツを再割り当てすることができます。私。それは新しいメモリフラグメントをとり、そこに値をコピーし、古いものを削除します。そのコンテンツへの古いポインタは無効になります。

+0

私はコピーがプッシュされるだけではわかりませんでした。私はC++ 11では 'std :: move()'が実行されていると考えました。修正はemplace_backを使用することになりますか?どのように私はこれを解決するだろうか? –

+1

@SeanM。 'emplace_back'は、コピーせずにオブジェクトを構築することを可能にします。しかし 'cars.back()'のアドレスはいつでも変更することができます。たぶん良い方法は、ポインタのベクトルを保持することです。おそらくは "重い"ユーザクラスのためのポインタベクトルを保持するための良いフォームであることを意図しています。メモリを手動で管理したくない場合は、_vector <[unique_ptr](http://www.cplusplus.com/reference/memory/unique_ptr/?kw=unique_ptr)_または_vector <[shared_ptr](http: //www.cplusplus.com/reference/memory/shared_ptr/?kw=shared_ptr)>_。 – ilotXXI

+1

@SeanM。あなたはそうです。このコードでは、一時オブジェクトはC++ 11以降_moved_になります。しかし、私はそれがこのクラスのために何らかの違いがあるとは思わない。とにかく、問題はコピーではありません。これは、アドレス変更可能またはローカル変数へのポインタです。 – ilotXXI

関連する問題