簡體   English   中英

std :: sort以嚴格的弱排序崩潰-與垃圾值比較

[英]std::sort crashes with strict weak ordering - comparing with garbage values

我編寫了一個比較功能,該功能應該比較像國際象棋這樣的游戲中玩家的兩個可能的移動選項。 每個“移動”都包含一個應該執行該移動的圖形和一個“點”,它將在其中移動。 點已被檢查,因此所有點都是有效的移動。 當我嘗試使用嚴格的弱排序和std :: sort函數對包含當前可用的所有移動的列表進行排序時,當我的compare函數在一次移動中遇到一些垃圾圖形指針時,我得到了SIGSEG。

我已經嘗試找出了垃圾指針的來源,但僅發現std :: sort函數以某種方式將其與所有其他動作混合在一起。 當我嘗試使用std :: stable_sort排序時,會發生相同的段錯誤。 由於我以前曾經有過一些事實,因此我也想談一下堆棧問題,但事實並非如此。

bool cmpWhite(White_Move m1, White_Move m2) {

    if (m1.f == nullptr) {
        return true;
    } else if (m2.f == nullptr) {
        return true;
    }

    int sum1 = 0;
    double avg1 = 0;
    Figure *f1 = m1.f;
    Point origin1 = f1->getCoordinatesAsPoint();
    int sum2 = 0;
    double avg2 = 0;
    Figure *f2 = m2.f;
    Point origin2 = f2->getCoordinatesAsPoint();

    Point p;

    movePiece(field_pub, f1, m1.p);
    std::vector<Point> moves = black_king->getAllNewPossiblePositions();
    for (int i = 0; i < moves.size(); i++) {
        p = moves[i];
        if (!black_king->isPositionBlocked(field_pub, p.x, p.y)) {
            sum1++;
            // avg1 += sqrt((p.x - target_pub.x) * (p.x - target_pub.x) + (p.y - target_pub.y) * (p.y - target_pub.y));
        }
    }
    p = black_king->getCoordinatesAsPoint();
    if (!black_king->isPositionBlocked(field_pub, p.x, p.y)) {
        sum1++;
    }
    // avg1 = (double)sum1;
    movePiece(field_pub, f1, origin1);

    movePiece(field_pub, f2, m2.p);
    moves = black_king->getAllNewPossiblePositions();
    for (int i = 0; i < moves.size(); i++) {
        p = moves[i];
        if (!black_king->isPositionBlocked(field_pub, p.x, p.y)) {
            sum2++;
            // avg2 += sqrt((p.x - target_pub.x) * (p.x - target_pub.x) + (p.y - target_pub.y) * (p.y - target_pub.y));
        }
    }
    p = black_king->getCoordinatesAsPoint();
    if (!black_king->isPositionBlocked(field_pub, p.x, p.y)) {
        sum2++;
    }
    // avg2 = (double)sum2;
    movePiece(field_pub, f2, origin2);
    std::cout << "cmp: " << sum1 << " " << sum2 << std::endl;
    return sum1 < sum2;
}
std::vector<White_Move> sortBestMovesForWhite(Figure **figures, int size, King *bKing, int **field, Point target) {
    target_pub = target;
    field_pub = new int *[FIELD_WIDTH];
    for (int x = 0; x < FIELD_WIDTH; x++) {
        field_pub[x] = new int[FIELD_HEIGHT];
        for (int y = 0; y < FIELD_HEIGHT; y++) {
            field_pub[x][y] = field[x][y];
        }
    }
    black_king = bKing;
    std::vector<White_Move> moves;
    for (int i = 0; i < size; i++) {
        Figure *f = figures[i];
        std::vector<Point> m_point = f->getAllNewPossiblePositions();
        for (int j = 0; j < m_point.size(); j++) {
            if (!f->isPositionBlocked(field, m_point.at(j).x, m_point.at(j).y)) {
                White_Move move = {f, m_point.at(j)};
                moves.push_back(move);
            }
        }
    }
    // std::stable_sort(moves.begin(), moves.end(), cmpWhite);
    std::sort(moves.begin(), moves.end(), cmpWhite);
    for (int x = 0; x < FIELD_WIDTH; x++) {
        delete[] field_pub[x];
    }
    delete[] field_pub;
    return moves;
}

在compare函數開始時, return true之一應該是return false std::sort的比較器必須滿足此處指定的條件: https : //en.cppreference.com/w/cpp/named_req/Compare 如果不是這種情況,則std::sort將具有未定義的行為。

正確的實現應類似於:

bool cmpWhite(White_Move m1, White_Move m2) {

    if (m1.f == nullptr) {
        return m2.f != nullptr;
    }
    if (m2.f == nullptr) {
        return false;
    }
    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM