【发布时间】:2022-01-07 08:47:09
【问题描述】:
昨天我正在处理一个令人烦恼的错误,该错误涉及一个旨在从共享指针向量中删除元素的函数。这是有问题的代码:
template <typename T>
void flush(
std::vector<std::shared_ptr<T>>& offers
) {
std::vector<unsigned int> idxs;
for (unsigned int i = 0; i < offers.size(); i++) {
if (!offers[i]->is_available()) {
idxs.push_back(i);
}
}
for (unsigned int i : idxs) {
offers[i] = offers.back();
offers.pop_back();
}
}
有时,offers 向量的元素会损坏(即它们会指向垃圾数据)。我最终更改了上面的代码以使用更标准的擦除删除习语:
template <typename T>
void flush(
std::vector<std::shared_ptr<T>>& offers
) {
offers.erase(
std::remove_if(
offers.begin(),
offers.end(),
[](std::shared_ptr<T> offer) { return !offer->is_available(); }
),
offers.end()
);
}
现在我没有看到与以前相同的问题(无论如何这更优雅)。但是,我想了解为什么在以前的代码没有的情况下它会起作用。我怀疑这与向量中保留的错误元素有关,或者可能与指针的引用计数发生了一些奇怪的事情有关,但我希望能深入了解这里到底发生了什么。
【问题讨论】:
-
您是否检查过您的第二个循环是否最终没有访问超出范围的向量?例如:如果存储在
idxs中的这些索引之一是最后一个(并且您有多个索引要删除),那么您最终会这样做 -
说得更极端一些,想象一下一个小数组的每个元素都被删除的情况。
-
啊,谢谢@UnholySheep,这对我来说很明显了!不敢相信我花了这么多时间试图弄清楚这一点......
标签: c++ shared-ptr stdvector