0

私はこの問題を数時間静かに座っていましたが、解決策を見つけることができません。いくつかのカスタム配列クラスを削除しようとし、それらをstd::vectorに変更したいと思います。

私は次のように宣言されたクラスメンバーを持っています:

std::vector<BaseCluster *> baseClusters;

クラスコンストラクターでは、ベクトルを特定のサイズに初期化しません。初期化せずにそのままにしておきます。以前は、ifを特定のサイズに初期化しようとしましたが(パフォーマンスを向上させ、多くの再割り当てを防ぐため)、ループ内の要素へのアクセス(印刷など)で問題が発生しました。これは、デフォルトのコンストラクター(BaseCluster型)をNULLオブジェクトとしてオブジェクトを初期化したためだと思います。

ただし、ループでは、このようなオブジェクトでベクトルを埋めます

baseClusters.push_back(new BaseCluster(current, score));

ループが終了した後、興味のないオブジェクトのクリーンアップを行います。

for (unsigned int i = 0; i < baseClusters.size(); i++) {
    // --- testing   
    if (baseClusters.at(i) == NULL) {
       wcout << i << ". object is NULL" << endl;
    }
    if (
      ((BaseCluster *) baseClusters.at(i))->getNode()->getSuffixedDocumentsCount() < minimalGroupSize
    ) {
        baseClusters.erase(baseClusters.begin() + i);
    }

    if (i >= noMoreBaseClustersThan) {
        baseClusters.erase(baseClusters.begin() + i);
    }
}

ここで、ベクトルを並べ替えます(スコアの降順で並べ替える必要があります)。ここで問題が発生します。

1.)並べ替えを使用する

sort(baseClusters.begin(), baseClusters.end()); 

まったくソートされません。また、BaseClusterクラスに実装された「operators<」または「operator>」はまったく変更されません。オペレーターは公開されており、次のようになります。

bool operator< (const BaseCluster * rhs) const {
    return m_score < rhs->m_score;
}

bool operator> (const BaseCluster * rhs) const {
    return m_score > rhs->m_score;
}

2.)述語/ファンクターを使用する

class BaseClusterComparator {
public:
    bool operator() (const BaseCluster * a, const BaseCluster * b) const {
        wcout << "BaseClusterComparator" << endl;
        wcout << a->getScore() << " <> " << b->getScore() << endl;
        if (a->getScore() > b->getScore()) {
            return -1;
        } else if (a->getScore() < b->getScore()) {
            return 1;
        } else {
            return 0;
        }
    }
};

クラスメンバーのgetScoreは次のようになります

float
BaseCluster::getScore() const {
    return m_score;
}

でソートを実行します

sort(baseClusters.begin(), baseClusters.end()), BaseClusterComparator());

約60〜70個のオブジェクトを並べ替えた後、getScore()メソッドにアクセスしようとすると、セグメンテーション違反が発生します。

Program received signal SIGSEGV, Segmentation fault.
0x00000000004773ec in BaseCluster::getScore (this=0x2ef1) at algorithm/BaseCluster.cpp:44
44      return m_score;

ベクトルの予約/サイズ変更により、NULLオブジェクト(BaseClassのデフォルトコンストラクターで構築された?!)があるように感じます。

そして今、問題を解決する方法に固執しています。私はここで何が間違っているのですか?私はここで尋ねる前に他の多くの関連するstackoverflowの質問を読んでいて、その後、あちこちで変更しましたが、セグメントから抜け出す方法はありませんでした。障害。私が知っている限り、私はNullオブジェクトを挿入していません(ループでテストされています)ので、コードに別の欠陥があるはずです。ポインタのベクトルに変更するのは静かで簡単な作業だと思っていましたが、今ではもっと複雑に見えます...

どうか、誰かがこの問題について私を助けてください。よろしくお願いします!

4

1 に答える 1

1

コンパレータが間違っています:

std::sortコンパレータのqsortとは異なります。以下の演算子と同じものを返す必要があります。例えば

class BaseClusterComparator {
public:
    bool operator() (const BaseCluster * a, const BaseCluster * b) const {
        return a->getScore() < b->getScore();
    }
};
于 2012-07-08T02:00:40.997 に答える