Vector 是不是;删除“;语句双重释放对象?

Vector 是不是;删除“;语句双重释放对象?,vector,stl,erase,Vector,Stl,Erase,“双重自由”下面的“删除”语句是否为对象 (...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(); //---

“双重自由”下面的“删除”语句是否为对象

(...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;
    }
}
(…对象列表是全局向量…)
向量<对象*>:迭代器it、eit、iter;
对象*p_对象;
向量死亡对象;
它=对象\列表\开始();
eit=对象\列表\结束();
//---收集所有死对象指向死对象向量的指针
for(;it!=eit;it++)
{
p_object=*it;
如果(p_object->is_dead()==false)
继续;
死物体。推回(p物体);
}
//---从全局对象列表中释放所有死对象
对于(iter=dead_objects.begin();iter!=dead_objects.end();iter++)
{
p_object=*iter;
它=对象\列表\开始();
eit=对象\列表\结束();
for(;it!=eit;it++)
{
if(*it!=p_对象)
继续;
对象\列表\擦除(它);
删除p_对象;
打破
}
}

我问这个问题是因为上面的
erase()
语句应该已经调用了一个对象的析构函数并释放了它,不是吗?

它看起来不会;如果有指向对象的指针向量,调用erase()删除其中一个对象只需从向量中删除指针。您仍然需要自己删除它-这是因为STL容器主要设计用于按值收集对象

这里有几点建议-在我看来,如果您使用STL算法,比如
std::find
,而不是手动循环所有向量,那么您的代码会更清晰。我不确定dead_objects vs object_list的意义是什么-通过将它们存储在临时向量中,您似乎没有获得任何好处,但是在将代码复制到临时向量中时可能会丢失一些东西。而且
std::vector
对于像这样的大量随机擦除并不理想,因为
erase
在线性时间内运行-
std::remove
然后再
erase
将是一种更有效的方法。例如:

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());
for(vector::iterator it=object_list.begin();it!=object_list.end();++it){
如果((*it)->是死的(){
删除*它;
*它=空;
}
}
object_list.erase(std::remove(object_list.begin()、object_list.end()、NULL)、object_list.end());

erase()
确实调用对象上的析构函数,但指针类型的析构函数(例如这里的
object*
)不执行任何操作—它不调用指针上的delete。如果你想让它调用delete,你需要使用一些对象(比如
auto_ptr
)来调用delete。

谢谢你的回答!但是您的上一个语句object_list.erase(std::remove(object_list.begin(),object_list.end(),NULL),object_list.end())不是吗;擦除所有对象,死的和活的?否-
remove
从列表中移除等于NULL的所有元素,并在最后一个有效元素之后返回一个迭代器。然后,
erase
调用将向量截断为新的长度。谢谢您的回答!!我有这个问题,因为在另一个程序中,我使用map,在调用erase()从map中删除对象*后,当我取消引用对象*时,程序崩溃了。(我使用的是VC++6),所以我想知道vector.erase()是否也会释放对象。