我正在做一个 "大 "项目,我被一个分段故障卡住了,最后我把这个故障缩小到一个比较简单的、可重复的例子。
我打算放两段代码: 首先,我把两段代码放在这里。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::vector<int> someVector;
printf("1\n");
someVector.push_back(1);
printf("2\n");
someVector.push_back(2);
printf("3\n");
someVector.push_back(3);
someVector.erase(someVector.begin());
someVector.erase(someVector.begin());
return 0;
}
这里,一切正常 好的。现在让我们试试更复杂一点的东西。让我们使用我自己定义的类的向量,而不是使用一个ints的向量。
注意: 我不是专家,可能在定义类的时候犯了错误。之所以在类的定义中有一个复制构造函数,是因为: 参数 变量,实际上是指向另一个类的指针(而不是int),我把它复制到真实例子的构造函数主体上。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class ActionType {
public:
std::string name;
int type;
int * parameters;
ActionType(const std::string _name, const int _type
);
ActionType(const ActionType &);
~ActionType(){
// Direct implementation of destructor
printf("DELETING\n");
delete parameters;
}
};
// Implementation of initializer
ActionType::ActionType(const std::string _name, const int _type)
: name(_name)
, type(_type)
, parameters(new int(5))
{
}
// Implementation of copy constructor
ActionType::ActionType(const ActionType & actionType)
: name(actionType.name)
, type(actionType.type)
, parameters(new int(*actionType.parameters))
{
printf("COPYING\n");
}
int main()
{
ActionType actionType("foo", 1);
std::vector<ActionType> actions;
printf("1\n");
actions.push_back(actionType);
printf("2\n");
actions.push_back(actionType);
printf("3\n");
actions.push_back(actionType);
actions.erase(actions.begin());
actions.erase(actions.begin());
return 0;
}
这一点,应该是大同小异的,但却抛出了错误。
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001618c70 ***
Aborted (core dumped)
问题是,在我的真实例子中,我需要一种方法来删除向量中的几项, 为了做到这一点,我有一些类似的东西。
for (int i (...)){
int indexToDelete = getIndex();
vector.erase(vector.begin()+indexToDelete);
}
我也可以用这样的方法
std::vector<int> indexes;
for (int i (...)){
int indexToDelete = getIndex();
indexes.push_back(indexToDelete);
}
vector.erase(indexes);
但我还没有找到任何可以做到这一点的函数。我看过其他的答案,他们用排序把所有要删除的项目放在最后,然后再调用pop_back,但看起来不是很干净。
总之,在 摘要:
有谁知道为什么在使用有向量的类时,擦除函数不能很好地工作?
我怎样才能在知道它们在向量中的索引的情况下删除几个项目?
你的类缺少赋值运算符。 这个 std::vector
要求您的类具有正确的复制语义,并且您的 ActionType
不具有正确的复制语义。
很简单,为你写的类增加一个赋值操作符。
#include <algorithm>
//...
class ActionType
{
//...
ActionType& operator=(const ActionType &);
//...
};
ActionType& ActionType::operator=(const ActionType &rhs)
{
if ( this != &rhs )
{
ActionType temp(rhs);
std::swap(temp.name, name);
std::swap(temp.type, type);
std::swap(temp.parameters, parameters);
} // <-- The temp is destroyed here, along with the contents.
return *this;
}
上面使用的是 互换 习惯用语来实现赋值运算符。
请注意,代码中的 现在的工作 添加赋值运算符时
编辑。
赋值运算符的另一种形式可以是:
class ActionType
{
//...
ActionType& operator=(ActionType);
//...
};
ActionType& ActionType::operator=(ActionType temp)
{
std::swap(temp.name, name);
std::swap(temp.type, type);
std::swap(temp.parameters, parameters);
return *this;
}
当你删除参数数组时 你需要提供一个[]
delete [] parameters;
否则你的程序会出现未定义的行为。
Sidenote > 将它保留为std::vector或std::array可能会更好。