使用GMP整数时出现分段错误(核心转储)

Segmentation fault (core dumped) while using GMP Integers

本文关键字:错误 核心 转储 分段 GMP 整数 使用      更新时间:2023-10-16

我用c++编写了一个简单的程序,使用gmp库,打印出由1(如1,11,111,11111,11111,…)和2001组成的数的模数;问题是当程序达到1的23位数字时,我得到一个错误说分段故障(核心转储)。你能指出问题在哪里吗?下面是我的代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <gmpxx.h>
int main(int argc, char** args){
    mpz_t currNumber;
    mpz_init(currNumber);   
    mpz_set_str(currNumber, "1", 10);
    while(mpz_sizeinbase(currNumber, 10) < 24){
        char* digits =  mpz_get_str(nullptr, 10, currNumber);
        strcat(digits, "1");
        mpz_set_str(currNumber, digits, 10);
        digits = nullptr;

        mpz_t r;
        mpz_init(r);    
        mpz_set_str(r, "1", 20);
        mpz_t divisor;
        mpz_init(divisor);  
        mpz_set_str(divisor, "2001", 20);

        mpz_mmod(r, currNumber, divisor);
        std::cout << "====>" << currNumber << " mod(2001) = " << r << "nnn";
        //Clean up
        mpz_clear(r);
        mpz_clear(divisor);     
    }
    std::cout << "Went until " << mpz_sizeinbase(currNumber, 10) << " digits !" << "n";
    ///Clean up
    mpz_clear(currNumber);
    return 0;
}

第一个明显的bug是:

    char* digits =  mpz_get_str(nullptr, 10, currNumber);
    strcat(digits, "1");

由mpz_get_str分配的缓冲区没有足够的空间让您将一个额外的字符连接到其内容上。

我想你可以用:

    char* digits =  mpz_get_str(nullptr, 10, currNumber);
    std::string more_digits = std::string(digits) + "1";
    free(digits);
    mpz_set_str(currNumber, more_digits.c_str(), 10);

1)既然你是在c++中,你应该使用std::string来进行大多数字符串操作,而不需要学习使用C字符串的晦涩之处。
2)如果我正确地理解mpz_get_str(尽管我自己从未使用过它),你需要释放它分配的缓冲区(正如我在这个建议的代码中所做的那样),以避免内存泄漏。