我有一些使用libgmp的代码。在某些时候,用户可以请求非常大数量的阶乘。不幸的是,这导致libgmp引发中止信号。
例如以下代码:
#include <cmath>
#include <gmp.h>
#include <iostream>
int main() {
mpz_t result;
mpz_init(result);
mpz_fac_ui(result, 20922789888000);
std::cout << mpz_get_si(result) << std::endl;
}
结果:
$ ./test
gmp: overflow in mpz type
Aborted
显然,产生的数字非常大。反正是否比中止更优雅地处理错误。这是一个基于GUI的应用程序,它中止是处理此类问题的最不可取的方式。
答案 0 :(得分:4)
根据mpz/realloc.c和mpz/realloc2.c中的代码,您似乎运气不佳。如果请求的内存太多,它就会这样做:
if (UNLIKELY (new_alloc > INT_MAX))
{
fprintf (stderr, "gmp: overflow in mpz type\n");
abort ();
}
答案 1 :(得分:3)
在应用程序中优雅地处理这些错误的最佳方法可能是分离辅助进程以执行GMP计算。如果帮助程序进程被SIGABRT
终止,则您的父进程可以检测到该进程并向用户报告错误。
(以下是我的原始答案,根据GMP文档有“未定义的结果” - 为了完整性而留在这里。)
如果为使用SIGABRT
的{{1}}安装信号处理程序,则可以捕获错误:
longjmp()
答案 2 :(得分:1)
使用abort()
覆盖LD_PRELOAD
。
编辑:为了使答案更加独立,我在这里复制了答案的文字:
如果将LD_PRELOAD设置为共享对象的路径,则该文件将在任何其他库(包括C运行时libc.so)之前加载。因此,要使用特殊的malloc()实现来运行ls,请执行以下操作:
$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
致JesperE的信用。