Swa*_*nil 2 c++ vector heap-memory
我有vector包含堆上分配的对象.我想从向量中删除一些元素.哪个是从vector中删除元素并删除它的最佳方法.
在以下代码中尝试了一种方法:
class MyObj
{
bool rem;
public:
MyObj(bool r) : rem(r) { cout << "MyObj" << endl; }
~MyObj() { cout << "~MyObj" << endl; }
bool shouldRemove() const noexcept { return rem; }
};
int main()
{
vector<MyObj*> objs;
objs.push_back(new MyObj(false));
objs.push_back(new MyObj(true));
objs.push_back(new MyObj(false));
objs.push_back(new MyObj(true));
auto itr = objs.begin();
while (itr != objs.end())
{
if ((*itr)->shouldRemove())
{
delete *itr;
*itr = nullptr;
itr = objs.erase(itr);
}
else
++itr;
}
// size will be two
cout << "objs.size() :" << objs.size() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你的循环很好,只要删除和delete对象(nullptr分配是不必要的).但是其余的代码容易出现内存泄漏.如果push_back()抛出,你会泄漏刚才的物体new.并且delete在循环结束后,您不是仍然在向量中的对象.
哪个是从vector中删除元素并删除它的最佳方法
的最佳选择是在所有不使用原始指针.将实际对象实例直接存储在向量中,让向量在移除它时为您破坏实例,并在向量本身超出范围时对其进行破坏:
int main() {
std::vector<MyObj> objs;
objs.emplace_back(false);
objs.emplace_back(true);
objs.emplace_back(false);
objs.emplace_back(true);
auto itr = objs.begin();
while (itr != objs.end()) {
if (itr->shouldRemove())
itr = objs.erase(itr);
else
++itr;
}
/* alternatively:
objs.erase(
std::remove_if(objs.begin(), objs.end(),
[](auto &o){ return o.shouldRemove(); }),
objs.end()
);
*/
// size will be two
std::cout << "objs.size() :" << objs.size() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
否则,如果需要存储指向动态分配对象的指针,至少使用智能指针来管理它们:
int main() {
std::vector<std::unique_ptr<MyObj>> objs;
objs.push_back(std::unique_ptr<MyObj>(new MyObj(false)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(true)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(false)));
objs.push_back(std::unique_ptr<MyObj>(new MyObj(true)));
/* alternatively, if you are using C++14 or later
objs.push_back(std::make_unique<MyObj>(false));
objs.push_back(std::make_unique_ptr<MyObj>(true));
objs.push_back(std::make_unique<MyObj>(false));
objs.push_back(std::make_unique<MyObj>(true));
*/
auto itr = objs.begin();
while (itr != objs.end()) {
if ((*itr)->shouldRemove())
itr = objs.erase(itr);
else
++itr;
}
/* alternatively:
objs.erase(
std::remove_if(objs.begin(), objs.end(),
[](auto &o){ return o->shouldRemove(); }),
objs.end()
);
*/
// size will be two
std::cout << "objs.size() :" << objs.size() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
202 次 |
| 最近记录: |