首页 文章

STL映射被mpz_class(GMP)值损坏

提问于
浏览
1

我有一个 std::map<mpz_class,int> (对于那些不熟悉的人来说, mpz_class 是一个非常大的整数的类容器,由GMP,Gnu Multiprecision Library定义) . 我使用自定义比较器,它使用GMP的 cmp() 功能 . 在 Map 中,我插入了几个具有正确值的 std::pair<mpz_class,int> (打印时它们是合理的) .

但是,我注意到 map::find 无法正常工作,因此我打印了比较器正在比较的内容 . 事实证明,第二个元素(键)始终是一个非常狂野的值整数值,如128957236027369832796823768439267,超出了我正在使用的整数的范围 .

是否存在某些我不知道的内存损坏?也许 mpz_class 不能以这种方式使用?我该如何解决这个问题?到目前为止,我还没有遇到过其他容器的这个问题 .

#include <map>
#include <gmpxx.h>
#include <iostream>

struct Equaler {
    inline bool operator()(const mpz_class a, const mpz_class b) const {
        std::cout << " about to return " << a << "," << b << "," << cmp(a,b) << "\n";
        return cmp(a, b);
    }
};

int main() {
    mpz_class x("38268");
    std::map<mpz_class,int,Equaler> map;
    map.insert(std::pair<mpz_class,int>(x,42));
    map.find(x);
    return 0;
}

输出:

about to return 38268,812462232382732367817613904064203084469901797507,-2

1 回答

  • 2

    问题是你的比较器 . std::map 期望比较器,如果第一个操作数应小于第二个,则返回true,否则返回false . 但 cmp 的工作方式不同 . 它不返回布尔值,它返回一个整数,处于三种可能状态之一:

    • 否定:lhs <rhs

    • 0:lhs == rhs

    • 正面:lhs> rhs

    但是,布尔上下文中的负整数和正整数都计算为true,因此 cmp 的结果无法正确转换为 std::map 期望的结果 . 改变这个:

    return cmp(a, b);
    

    对此:

    return cmp(a, b) < 0;
    

相关问题