You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GMP库mpz_t变量赋值异常 欧拉29题大整数去重实现出错

问题原因

你的判断是准确的,vector中存储的所有元素都是同一个rop变量的内存地址。每次循环中调用mpz_ui_pow_ui修改rop的值时,vector里所有指针指向的内容都会同步更新,所以对比时会永远判定为相等,自然无法插入新值。如果直接在push_back后调用mpz_clear(rop),vector里存储的所有指针都会变成野指针,访问时会直接触发内存错误。

修复方案
  1. 不要直接存储复用的rop变量的指针,每次确认要存储新的幂运算结果时,单独初始化一个新的mpz_t实例,将当前rop的值拷贝到新实例中,再将新实例的指针存入vector。
  2. 程序运行结束后,遍历vector释放所有存储的mpz_t实例,避免内存泄漏。
修改后的完整代码
#include <iostream>
#include <vector>
#include <chrono>
#include "gmp.h"

using namespace std;

int main()
{
    auto start = std::chrono::high_resolution_clock::now();
    
    int solution = 0;
    bool found = false;
    int r = 10;
    
    mpz_t rop;
    mpz_init(rop);
    
    mpz_t temp;
    mpz_init(temp);
    
    vector<mpz_t*> numbers;
    
    // 测试范围可按需改回2~100
    for(int a = 2; a <= 5; a++)
    {
        for(int b = 2; b <= 5; b++)
        {
            mpz_ui_pow_ui(rop, a, b);
            found = false;
            for(int i = 0; i < numbers.size(); i++)
            {
                mpz_set(temp,*(numbers.at(i)));
                r = mpz_cmp(rop,temp);
                if(r == 0)
                {
                    found = true;
                    break;
                }
            }
            if(found == false)
            {
                // 新建mpz_t实例,拷贝当前rop的值再存入vector
                mpz_t* new_num = new mpz_t;
                mpz_init(*new_num);
                mpz_set(*new_num, rop);
                numbers.push_back(new_num);
                solution++;
            }
        }
    }

    auto done = std::chrono::high_resolution_clock::now();
    cout << "Solution: " << solution << endl << endl;
    cout << "Program completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(done - start).count() << " milliseconds." << endl;

    // 释放所有存储的mpz_t资源
    for(auto num : numbers) {
        mpz_clear(*num);
        delete num;
    }
    // 释放临时变量资源
    mpz_clear(rop);
    mpz_clear(temp);
    
    return 0;
}
额外优化建议

如果要计算a、b范围到100的正式题解,用vector遍历查重的效率较低,你可以改用std::set结构存储结果,利用set自带的去重特性简化代码,需要注意自定义mpz_t的比较逻辑,或者直接将mpz_t转为字符串存入set即可。


内容的提问来源于stack exchange,提问作者MFerguson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:57:04