std :: sort以严格的弱排序崩溃-与垃圾值比较

时间:2019-04-23 16:15:05

标签: c++

我编写了一个比较功能,该功能应该比较像国际象棋这样的游戏中玩家的两个可能的移动选项。每个“移动”都包含一个应该执行该移动的图形和一个“点”,它将在其中移动。点已被检查,因此所有点都是有效的移动。当我尝试使用严格的弱排序和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;
}

1 个答案:

答案 0 :(得分:1)

在比较功能开始时,您的return true之一应该是return falsestd::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;
    }
    ...
}