Search code examples
cflint

Seeing a segfault when I try to evaluate a polynomial. What am I doing wrong?


I am trying to use the FLINT Fast Library for Number Theory (https://flintlib.org/) to evaluate a multivariate polynomial over the integers mod a prime p. My code seems to follow the documentation, but still results in a segmentation fault.

Here is a minimal example that reproduces the problem:

#include"flint/fmpz_mod_mpoly.h"

int main(){
   const char *x[4]={"d","m1","s","t"};
   fmpz *vals=(fmpz []){3,5,7,11};
   slong p=13,c=0;
   fmpz_mod_mpoly_ctx_t C;
   fmpz_mod_mpoly_t E;

   fmpz_mod_mpoly_ctx_init(C,4,ORD_LEX,&p);
   fmpz_mod_mpoly_init(E, C);

   fmpz_mod_mpoly_set_str_pretty(E,"-d",x,C);

   //this is the line that segfaults
   fmpz_mod_mpoly_evaluate_all_fmpz(&c,E,&vals,C);

   flint_printf("Solution is %wd\n",c);
   fmpz_mod_mpoly_clear(E,C);
   fmpz_mod_mpoly_ctx_clear(C);
   return 0;
}

The segmentation fault happens inside a function in the library, so clearly either there is a bug in the library itself or I'm using it incorrectly. I'm guessing the latter. What am I doing wrong?

Edit: Added a comment to identify which line the segfault happens on. I've also posted the call stack below:

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libflint.19.0.dylib                 0x103747d05 fmpz_mod + 37
1   libflint.19.0.dylib                 0x103936dfc fmpz_mod_mpoly_evaluate_all_fmpz + 255
2   Ftest                               0x102640e98 main + 264
3   dyld                              0x7ff807368366 start + 1942

Solution

  • The vals parameter of fmpz_mod_mpoly_evaluate_all_fmpz has the type fmpz *const*. Looking at the source code, it iterates over the outer dimension, and passes vals[i] to another function which expects a fmpz_t. And the documentation says:

    By default, an fmpz_t is implemented as an array of fmpz’s of length one

    Therefore, you should make vals an array where each element points to a 1-element array:

    fmpz *vals[4] = {(fmpz[]){3},(fmpz[]){5},(fmpz[]){7},(fmpz[]){11}};
    

    Unfortunately you can't define this as a simple 2D array because that type won't be compatible with a pointer to a pointer.