-1

次のクラスがあり、デストラクタが呼び出されて 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 は int が 3 つしかないクラスです。このエラーを引き起こしている明らかな何かがありますか?

クラス 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;
    }
4

4 に答える 4

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);
}
于 2013-09-25T18:44:53.900 に答える
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;

コピーコンストラクターと同じ問題...

于 2013-09-25T18:48:34.720 に答える
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 );
于 2013-09-25T18:45:22.247 に答える
0

コピー コンストラクタが間違っています。次のようなものを使用するだけでなく、ディープコピーを実行する必要があります

b = src.b;

マップの各メンバーをソースから宛先にコピーする必要があります。

そしてあなたの代入演算子も。

于 2013-09-25T18:43:36.853 に答える