使用 GMP 整数时出现分段错误(核心已转储)
Segmentation fault (core dumped) while using GMP Integers
我使用 gmp 库用 C++ 编写了一个简单的程序,它打印出由 1(如 1、11、111、1111、11111 等)和 2001 组成的数字的模数;问题是当程序达到 1 的 23 位时,我收到一条错误消息,提示 Segmantation fault(core dumped)。你能指出问题出在哪里吗?这是我的代码:
#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 << "\n\n\n";
//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;
}
第一个明显的错误是:
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(尽管我自己从未使用过),您需要释放它分配的缓冲区(正如我在建议的代码中所做的那样)以避免内存泄漏。
我使用 gmp 库用 C++ 编写了一个简单的程序,它打印出由 1(如 1、11、111、1111、11111 等)和 2001 组成的数字的模数;问题是当程序达到 1 的 23 位时,我收到一条错误消息,提示 Segmantation fault(core dumped)。你能指出问题出在哪里吗?这是我的代码:
#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 << "\n\n\n";
//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;
}
第一个明显的错误是:
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(尽管我自己从未使用过),您需要释放它分配的缓冲区(正如我在建议的代码中所做的那样)以避免内存泄漏。