Попытка удалить уже удаленный указатель в деструкторе

У меня есть следующий класс, и я получаю ошибку, когда вызывается деструктор, и он пытается удалить указатели на 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 — это класс, который имеет всего три целых числа. Есть ли что-то очевидное, что вызывает эту ошибку?

класс 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;
}

-1

Решение

В вашем конструкторе копирования есть очевидная проблема:

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);
}
3

Другие решения

Следующий код:

   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 );
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;

Те же проблемы с конструкторами копирования …

1

Ваш конструктор копирования неверен. Вам нужно сделать глубокую копию, а не просто использовать что-то вроде

b = src.b;

вам нужно скопировать каждый элемент карты из источника в пункт назначения.

И ваш оператор присваивания тоже.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector