2

以下の「delete」ステートメントはオブジェクトを「二重に解放」しますか?

(...object_list is a global vector<object*>...)

vector< object * >::iterator     it, eit, iter;
object *p_object;
vector< object * >   dead_objects;

it  = object_list_.begin();
eit = object_list_.end();

//---collect pointers of all dead objects to dead_objects vector
for ( ; it != eit; it++ )
{
    p_object = *it;
    if ( p_object->is_dead() == false )
        continue;

    dead_objects.push_back( p_object );
}

//---free every dead object from the global object_list
for ( iter = dead_objects.begin(); iter != dead_objects.end(); iter++ )
{
    p_object = *iter;

    it  = object_list_.begin();
    eit = object_list_.end();

    for ( ; it != eit; it++ )
    {
        if ( *it != p_object )
            continue;

        object_list_.erase( it );
        delete p_object;
        break;
    }
}

erase()上記のステートメントはオブジェクトのデストラクタを呼び出してすでに解放しているはずなので、質問しますね。

4

2 に答える 2

2

erase()オブジェクトのデストラクタを呼び出しますが、ポインタ型のデストラクタ(object *ここなど)は何もしません。ポインタのdeleteを呼び出しません。削除を呼び出す場合は、削除を呼び出すオブジェクト(など)を使用する必要がありますauto_ptr<object *>

于 2010-08-11T01:48:36.177 に答える
0

そうではないようです。オブジェクトへのポインタのベクトルがある場合、それらの1つを削除するためにerase()を呼び出すと、ベクトルからポインタが削除されます。それでも自分で削除する必要があります。これは、STLコンテナが主にオブジェクトを値で収集するように設計されているためです。

いくつかの提案-IMOを使用するとstd::find、すべてのベクトルを手動でループする代わりに、のようなSTLアルゴリズムを使用した方がコードが明確になります。dead_objectsとobject_listのポイントが何であるかはわかりません。一時的なベクトルに格納しても何も得られないようですが、コードをSOにコピーする際に何かが失われた可能性があります。また、線形時間で実行されるstd::vectorため、このような多くのランダムな消去には最適ではありません。その後に、より効率的なアプローチが続きます。例えば:erasestd::removeerase

for(vector<object*>::iterator it = object_list.begin(); it != object_list.end(); ++it) {
    if((*it)->is_dead()) {
        delete *it;
        *it = NULL;
    }
}
object_list.erase(std::remove(object_list.begin(), object_list.end(), NULL), object_list.end());
于 2010-08-11T01:47:45.740 に答える