我正在尝试用 C ++ 学习矢量,所以我写了一个非常基本的代码。基本上,我有一个向量,其中包含指向人员结构的指针。这是这样的:
typedef struct _person
{
unsigned long id;
char* name;
unsigned long age;
}person;
然后,我有一个这样定义的向量:
vector<person*> MyPersons;
然后,为了测试,我创建了一些人物结构,并通过push_back
函数将它们推送到矢量。现在,例如,我想从我的向量中移除第一个年龄为25岁的人。所以,我所做的是在向量中搜索并获取该人的索引,然后从向量中删除该索引。
for(size_t i = 0; i < MyPersons.size(); i++)
{
pperson = MyPersons.at(i);
if(pperson->age == 25)
{
index = i;
break;
}
}
MyPersons.erase(MyPersons.begin() + index )
现在,它应该从列表中删除该项,对吗?但是,相反,它给了我错误:
Debug Assertion失败!
表达式:向量擦除迭代器超出范围
但这是不可能的。我用Visual Studio调试我的代码,我发现索引值是有效的。 MyPersons大小为5,索引为2.
任何帮助非常感谢。 此致
答案 0 :(得分:4)
问题可能是index
初始化为不在MyPersons
范围内的值,因此如果找不到该值,则会收到错误。
您应该对这些类型的任务使用标准算法,删除您可以使用的年龄为25岁的第一个person*
:
auto itr = std::find_if(MyPersons.cbegin(), MyPersons.cend(),
[] (person* pperson) { return pperson->age == 25; });
if (itr != MyPersons.cend()) MyPersons.erase(itr);
要删除年龄为25岁的所有 person*
,您可以使用:
MyPersons.erase(std::remove_if(MyPersons.begin(), MyPersons.end(),
[] (person* pperson) { return pperson->age == 25; }),
MyPersons.end());
使用标准算法比使用手动循环更可取。意图更清晰,结果代码通常不那么冗长,最重要的是,标准算法更可能是正确的。
此外,您可能会在std::vector
中以错误的方式存储指向数据的指针。
答案 1 :(得分:4)
你不需要typedef struct _person
序言,这是C-ism。
struct person
{
unsigned long id;
std::string name;
unsigned long age;
}
您也不需要new
个对象,它们可以是值
std::vector<person> people;
删除第一个25岁的人:
auto it = std::find_if(people.begin(), people.end(), [](person & p) { return p.age = 25; });
if (it != people.end()) people.erase(it);
删除所有25岁的人:
auto it = std::remove_if(people.begin(), people.end(), [](person & p) { return p.age = 25; });
people.erase(it, people.end());