pythoncpython-3.xsegmentation-faultpython-embedding

Segmentation Fault while using Python lib in C with Python.h


This is my first time asking a question on stack overflow so please bear with me

I am trying to create a calculator in c as a project but I am getting a segmentation fault when evaluating a algebraic expression for second time using a python lib inside c using Python.h

At first I was using the eval function directly provided by the python interpreter but after reading about why eval can be dangerous I used a python lib named NumExpr as suggested here but when I use that python library to evaluate the algebraic expression I get a segmentation fault on entering the expression second time (it works for the first time)

Here is the example code :

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <Python.h>

void my_pause()
{
    int c;
    printf("\n  Press the enter key to continue...");
    fflush(stdout);
    while ((c = getchar()) != '\n' && c != EOF) {}
}

void main()
{
    char selec[8], temp;

    while(1)
    {
        main:

        printf("Enter here : ");
        scanf("%s" , selec);
        scanf("%c" , &temp); //this scanf is necessary as it solves the input buffer

        if(strcmp(selec,"math-exp")==0)
        {
            printf("\n\n  Please note the opreators : ");
            printf("\n    for addition '+'");
            printf("\n    for subtraction '-'");
            printf("\n    for multiplication '*'");
            printf("\n    for division '/'");
            printf("\n    for exponential power '**'");
            printf("\n    for percentage '%%'");
            printf("\n    for knowing about various functions that can be used please check documentation");

            //I had to print this using printf and not by python print itself is to solve the EOL error
            printf("\n\n  Enter the mathematical expression : ");
            Py_Initialize();
            PyRun_SimpleString("import numexpr as ne");
            PyRun_SimpleString("math_exp = input()");
            //I had to print this using printf and not by python print itself is to solve the EOL error
            printf("\n  The answer is : ");
            fflush(stdout);
            PyRun_SimpleString("print(math_exp)");
            Py_Finalize();

            my_pause();
            system("clear");
            goto main;
        }
        else if(strcmp(selec,"exit")==0)
        {
            exit(0);
        }
    }
}

This works perfectly fine for the first time but if you enter 'math-exp' for the second time to enter another expression it will show the segmentation fault. I am using linux mint, gcc 9.4.0, python 3.8. Below is the command I am using to compile the code :

gcc test.c -o test.bin -I"/usr/include/python3.8" -L"/usr/lib/python3.8" -lpython3.8

Thanks in advance for the help!


Solution

  • Calling Py_Finalize multiple times creates memory leaks. Just move your Py_Finalize line before exit(0) This bug has been opened in 2007, and just closed last month. https://bugs.python.org/issue1635741 Solved in python 3.11.