5

、およびStudent クラスのメンバー フィールドであるオブジェクトclass Studentへのポインターのベクトルがある宿題の問題があります。Student

vector<Student*> vectorName;

正しい(?)メモリ管理を行うために、Student クラスでデストラクタを次のように宣言しました。

Student::~Student() {
  for(int i=0; i<vectorName.size(); i++){
    delete vectorName.at(i);
  }
}

これは本当にメモリをヒープから正しく解放しますか、それとももっと良い方法がありますか?

4

3 に答える 3

5

これは主に、Student*参照が保存されている場所によって異なります。Student*インスタンスに、他の場所を参照していない学生の個人リストがある場合、実行していることにより、多くのダングリングポインタが生成されます。

含まれているオブジェクトのデストラクタを破棄することstd::vectorが暗黙的に呼び出される場合、これは、含まれているオブジェクトがStudent*ポインタのスペースだけである場合、手動で実行する必要があることを意味します。同じStudent*を複数のコレクションに保存します。

要約すると:

  • ベクトルにオブジェクトへの参照のみが含まれている場合は、オブジェクトの削除をStudent*実行する必要があります。
  • コレクション内のを削除するStudent*と、他のコレクション内のそのポインタが無効になり、問題が発生します
  • 共有学生の場合は、安全に削除できるように、(ベクトルを破棄している間)参照がなくなったことを確認する方法を見つける必要があります。(スマートポインターを参照してください。手動で参照をカウントすることもできますが、それは車輪の再発明になります)
于 2012-11-13T16:53:59.153 に答える
2

のアイテムを割り当てた場合はvectornamenew Studentはい。vectorName.at(i)ただし、この時点以降、aが指すデータは破棄されるため、プログラム内の他の場所からアクセスしてはならないことを覚えて おく必要があります。

于 2012-11-13T16:53:10.703 に答える
2

ベクターが生徒を所有している場合 (つまり、それらを削除する責任がある場合)、ポインターをまったく使用しないでください (ポリモーフィズムが必要な場合を除きますが、質問でそれを述べていないので、そうではないと思います)。これを行うと、dtor、コピー ctor、コピー代入演算子を明示的に定義する必要がなくなります。ゼロのルールを参照してください。

vector<Student> vectorName;

オブジェクトをベクターに挿入するときにオブジェクトをコピーするオーバーヘッドが必要ない場合は、オブジェクトを移動するか、次を使用しますemplace_back

vectorName.push_back(std::move(student));
vectorName.emplace_back("John", 42);
于 2012-11-13T16:56:50.223 に答える