2

これは問題ではなく、答えてもらいたい質問です。

パーティクルを持つ 2D アプリケーションを作成しています。クリック ハンドラーでは、次のコードを記述しました。

Particle *tempp = new Particle();
tempp->setPosition(mx, my);
particles.push_back(tempp); // typeof particles = std::list<Particle*>
delete tempp; // <- this line is the problem

クリックすると、マウスの位置にパーティクルが 1 つ作成されます。約 1 秒後に消えますが、問題なく動作します。消えたら、もう一度クリックして新しいパーティクルを作成します。

しかし、画面上にパーティクルが 1 つ残っているときにクリックすると、プログラムがフリーズして動作を停止します。

クラスの私のデストラクタとそのParticle親のデストラクタは両方とも空です。

delete一度に複数のパーティクルを使用したり、フレームごとに複数のパーティクルを使用したりしても、プログラムを呼び出さずに正常に実行されます。この凍結の問題を引き起こしているのは何なのかと思っています。

4

5 に答える 5

5

投稿されたコードに基づいて、particlesコンテナーにはダングリング ポインターが含まれます。これらを逆参照しようとすると、未定義の動作になります。それらは後で使用されると思います。そうでなければ、それらの保管は無意味に思えます。

呼び出しpush_back()では、ポイント先のオブジェクトはコピーされませんが、ポインターの値 (動的に割り当てられたオブジェクトのメモリ アドレス) がコピーされます。Particle安価にコピーでき、コピー可能で、ポリモーフィックな動作が不要な場合はParticle、コンテナに格納するだけです。それ以外の場合は、 などのスマート ポインターを使用して、コンテナーから削除されstd::unique_ptrたときに を自動的に破棄することをお勧めします。Particle

于 2013-05-09T15:02:57.800 に答える
3

私が見たときnew、そして数行後deleteに、スタックが使用されていることを確認したいと思います。巨大でない限りParticle(私は疑わしい)、コードを次のように変更できます。

Particle tempp;
tempp.setPosition(mx, my);
particles.push_back(tempp); // change particles to std::list<Particle>

プレスト。書くコードが減り、爆発することはありません。

于 2013-05-09T15:10:05.420 に答える
3

ポインターをリストにプッシュするときは、実際のポインターのコピーをプッシュするだけで、ポインターが指すもののコピーは作成しません。これは、同じメモリを指す2 つのpush_backポインターがあることを意味します。

その後、そのメモリを解放すると、解放されたメモリを指しているポインターがあり、そのポインターは無効になります。

于 2013-05-09T15:03:19.850 に答える
2

私が信じている解決策は、コードの 3 行目にあります。粒子は粒子へのポインターのベクトルであることに注意してください。3 行目では、ポインターのコピーを作成し、それをリストに挿入します。次の行で、そのポインタが指すメモリの割り当てを解除します。リストには粒子は保存されません。単に粒子のメモリ アドレスが保存されるだけです。そのため、粒子を削除するときに、有効なデータを含むメモリを再利用するようコンパイラに指示します。

したがって、4行目にコメントすると問題は解決しますが、実際にクラッシュするわけではありません-クラッシュする理由はありません。可能性の高いシナリオは、以前はyoursでしたが、3 行目で解放されたメモリで何かをしようとするとクラッシュすることです。

修正として、リストに実際のパーティクルを格納することができます。

于 2013-05-09T15:08:53.263 に答える
2

をコンテナに入れてpointerから削除していますが、これは問題です。の内容でpush_backはなく の値をコピーするため、 を呼び出すと、コンテナ内の は無効になります。これで、ダングリング ポインターができました。これを逆参照すると、これは未定義の動作になりますが、クラッシュする可能性が最も高くなります。pointerpointerdeletepointer

于 2013-05-09T15:04:00.650 に答える