我有以下类,我在调用析构函数时遇到错误,并尝试删除指向a和b的指针。看起来它们不存在。 这是触发问题的代码行:
unordered_map<string,Stock>* SDict = new unordered_map<string,S>();
SDict->insert(make_pair("38363",S("38363",i,w)));
标题
class O{
public:
O();
~O();
O(const O& tocopy);
O& operator=(const O& toassign);
private:
unordered_map<int,PQL>* b;
unordered_map<int,PQL>* a;
};
来源
O::O(){
a = new unordered_map<int,PQL>();
b = new unordered_map<int,PQL>();
}
O::~O(){
delete b; //I get the exception here- b doesn't exist before the delete.
delete a;
}
O& O::operator=(const O& src){
if(this != &src){
delete b;
delete a;
b = new unordered_map<int,PQL>();
b = src.b;
a = new unordered_map<int,PQL>();
a = src.a;
}
return *this;
}
O::O(const O& src){
b = new unordered_map<int,PQL>();
b = src.b;
a = new unordered_map<int,PQL>();
a = src.a;
}
PQL是一个只有三个整数的类。有什么明显的东西会导致这个错误吗?
class O是以下类的数据成员:
标题
class S{
public:
S();
S(string sid, vector<string>* indexids, vector<double>* sw);
~S();
S(const S& tocopy);
S& operator=(const S& toassign);
private:
string sid;
O* o;
vector<Strategy*> ts;
unordered_map<string,double>* iw;
};
来源
S::S(){}
S::S(string sid, vector<string>* iis, vector<double>* sw){
sid = sid;
iw = new unordered_map<string,double>();
o = new o();
if(iis->size() == sw->size()){
for(size_t i=0; i<iis->size(); i++){
string key = iis->at(i);
if(iw->count(key) == 0 ){
double weighting = sw->at(i);
iw->insert(make_pair(key,weighting));
}
else{
throw new exception();
}
}
}
else{
throw new exception();
}
}
S::S(const S& rhs){
sid = rhs.sid;
ts = rhs.ts;
o = new O();
o = rhs.o;
iw = new unordered_map<string,double>();
iw = rhs.iw;
}
S& S::operator=(const S& src){
if(this != &src){
delete o;
delete iw;
sid = src.sid;
ts = src.ts;
o = new o();
o = src.o;
iw = new unordered_map<string,double>();
iw = src.iw;
}
return *this;
}
S::~S(){
delete o;
delete iw;
}
答案 0 :(得分:3)
复制构造函数中存在一个明显的问题:
O::O(const O& src){
b = new unordered_map<int,PQL>();
b = src.b;
a = new unordered_map<int,PQL>();
a = src.a;
}
赋值确实分配了错误的实体:它指定指针,即赋值b = src.b
泄漏刚刚分配的内存并复制指针。你可能想写:
O::O(O const& src)
: b(new std::unordered_map<int, PQL>(*src.b)
, a(new std::unordered_map<int, PQL>(*src.a)
{
}
注意,您的赋值运算符不异常安全!一般猜想是,如果您的代码需要检查自我分配以便在自我分配的情况下工作,那么它不是例外安全。
赋值的规范实现利用了复制构造函数和析构函数,并使用另一个常用函数swap()
来交换资源:
O& O::operator= (O other) {
this->swap(other);
return *this;
}
void O::swap(O& other) {
using std::swap;
swap(this->b, other.b);
swap(this->a, other.a);
}
答案 1 :(得分:1)
以下代码:
b = new unordered_map<int,PQL>();
b = src.b;
a = new unordered_map<int,PQL>();
a = src.a;
应改为:
b = new unordered_map<int,PQL>();
*b = *src.b;
a = new unordered_map<int,PQL>();
*a = *src.a;
复制ctor和赋值运算符。因此它会复制地图内容而不是复制指针,这是错误的行为。但更好的方法是:
b = new unordered_map<int,PQL>( *src.b );
a = new unordered_map<int,PQL>( *src.a );
答案 2 :(得分:1)
您的代码有几个问题
O& O::operator=(const O& src){
if(this != &src){
delete b;
delete a;
//b will point to newly allocated memory
b = new unordered_map<int,PQL>();
//now you set b to point to the same unordered map as src (double deletion will occur)
//you will leak the memory you just allocated
b = src.b;
复制构造函数的问题......
答案 3 :(得分:0)
你的拷贝构造函数是错误的。你需要做一个深层复制,而不是只使用像
这样的东西b = src.b;
您需要将地图的每个成员从源复制到目标。
也是你的任务操作员。