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_对象;
向量
我问这个问题是因为上面的
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()是否也会释放对象。