for (int j = 0; j < height + 2; j ++){
for (int i = 0; i<width+2; i++){
printw("#");
}
printw("\n");
}
当从向量中删除某些内容时,此代码在for循环的开头崩溃。我不懂为什么。如果有帮助,我正在使用Visual Studio 2015
答案 0 :(得分:11)
erase
返回下一个迭代器。
if ((*a) == 2)
{
delete a;
it = intList.erase(it);
}
编辑:
remove()
和remove_if()
将复制元素(此处为指针),最后将有多个指向同一整数的元素,如果您尝试释放它们,则将剩下悬挂的指针。 / p>
考虑矢量有4
个元素,看起来像
0x196c160 0x196bec0 0x196c180 0x196bee0
可能会想使用erase-remove
惯用语
auto temp = remove_if(vec.begin(),vec.end(),[](const auto &i){return *i==2;});
现在看起来像
0x144aec0 0x144b180 0x144b180 0x144aee0
temp
将指向3rd
元素和一个
for(auto it=temp;it!=vec.end();it++)
delete *it;
现在第二个元素是一个悬空指针。
编辑2:
如果您在复制元素之前delete
,可以解决以上问题。请查看@Dietmar的答案。
答案 1 :(得分:3)
最好使用std::vector<std::unique_ptr<int>>
(如果不需要指针,甚至可以使用std::vector<int>
)。
然后只使用擦除删除习惯用语:
std::vector<int> intList{3, 2, 1};
intList.erase(std::remove(intList.begin(), intList.end(), 2), intList.end());
或
std::vector<std::unique_ptr<int>> intList;
intList.puch_back(std::make_unique<int>(3));
intList.puch_back(std::make_unique<int>(2));
intList.puch_back(std::make_unique<int>(1));
intList.erase(std::remove_if(intList.begin(), intList.end(),
[](const auto& p){ return *p == 2; }),
intList.end());
如果您确实需要原始拥有指针,则可以使用partition
使用变体:
std::vector<int*> intList{ new int {3}, new int {2}, new int{1} };
auto it = std::partition(intList.begin(), intList.end(),
[](const auto& p){ return *p != 2; });
std::foreach (it, intList.end(), [](int* p) { delete p; });
intList.erase(it, intList.end());
最后,如果您确实需要手动执行此操作,则必须将擦除行固定为:
it = intList.erase(it);
拥有:
std::vector<int*> intList{ new int {3}, new int {2}, new int{1} };
for (auto it = intList.begin(); it != intList.end(); /*Empty*/) {
int *p = *it;
if (*p == 2) {
delete p;
it = intList.erase(it);
} else {
++it;
}
}
答案 2 :(得分:2)
该代码导致迭代器无效。
您要删除一个,然后希望您的迭代器(只是一个指针)知道发生了什么。
如果您必须遍历整个向量,则考虑保留/丢弃并使用该向量的临时向量。
或者更好,只是使用find http://www.cplusplus.com/reference/algorithm/find/
答案 3 :(得分:2)
如果您查看documentation,擦除功能将返回下一个迭代器。就您而言,使用it = intList.erase(it)
是解决方案。在c ++ 11之后,其他容器中的所有擦除功能都遵循相同的想法。
答案 4 :(得分:2)
简单的答案是:您不知道!取而代之的是,您使用两步方法:首先删除元素,然后调整容器的大小。使用原始指针会使事情稍微复杂一些,但仍然可以实现:
auto end = std::remove_if(intList.begin(), intList.end(),
[](int *ptr){ return *ptr == 2 && (delete ptr, true); });
intList.erase(end, endList.end());
尝试在std::vector
上进行迭代时擦除单个元素具有非线性的最坏情况复杂度。