0

So from what I understand, a SIGSEGV segmentation fault is most likely caused by either trying to access memory you aren't allowed to or dereferencing a null pointer. If I am wrong in my understanding of this, please correct me as you please. As someone who is still rather new to programming, I am having trouble finding the solution to this error in this Multiplication table problem.

main.cpp:

#include <Python.h>
#include <iostream>
//#include <Windows.h>
#include <cmath>
#include <string>

using namespace std;

/*
Description:
    To call this function, simply pass the function name in Python that you wish to call.
Example:
    callProcedure("printsomething");
Output:
    Python will print on the screen: Hello from python!
Return:
    None
*/
void CallProcedure(const string& pName)
{
    char *procname = new char[pName.length() + 1];
    std::strcpy(procname, pName.c_str());

    Py_Initialize();
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("import os");
    PyRun_SimpleString("sys.path.append(os.getcwd())");
    PyObject* my_module = PyImport_ImportModule("python_modules.my_module");
    PyErr_Print();
    PyObject* my_function = PyObject_GetAttrString(my_module, procname);
    PyObject* my_result = PyObject_CallObject(my_function, NULL);
    Py_Finalize();

    delete[] procname;
}

/*
Description:
    To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send
Example:
    int x = callIntFunc("PrintMe","Test");
Output:
    Python will print on the screen:
        You sent me: Test
Return:
    100 is returned to the C++
*/
int callIntFunc(const string& proc, const string& param)
{
    char *procname = new char[proc.length() + 1];
    std::strcpy(procname, proc.c_str());

    char *paramval = new char[param.length() + 1];
    std::strcpy(paramval, param.c_str());


    PyObject *pName, *pModule, *pDict, *pFunc, *pValue = nullptr, *presult = nullptr;
    // Initialize the Python Interpreter
    Py_Initialize();
    // Build the name object
    pName = PyUnicode_FromString((char*)"python_modules.my_module");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, procname);
    if (PyCallable_Check(pFunc))
    {
        pValue = Py_BuildValue("(z)", paramval);
        PyErr_Print();
        presult = PyObject_CallObject(pFunc, pValue);
        PyErr_Print();
    }
    else
    {
        PyErr_Print();
    }
    //printf("Result is %d\n", _PyLong_AsInt(presult));
    Py_DECREF(pValue);
    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);
    // Finish the Python Interpreter
    Py_Finalize();

    // clean
    delete[] procname;
    delete[] paramval;


    return _PyLong_AsInt(presult);
}

/*
Description:
    To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send
Example:
    int x = callIntFunc("doublevalue",5);
Return:
    25 is returned to the C++
*/
int callIntFunc(const string& proc, int param)
{
    char *procname = new char[proc.length() + 1];
    std::strcpy(procname, proc.c_str());

    PyObject *pName, *pModule, *pDict, *pFunc, *pValue = nullptr, *presult = nullptr;
    // Initialize the Python Interpreter
    Py_Initialize();
    // Build the name object
    pName = PyUnicode_FromString((char*)"python_modules.my_module");
    // Load the module object
    pModule = PyImport_Import(pName);
    // pDict is a borrowed reference
    pDict = PyModule_GetDict(pModule);
    // pFunc is also a borrowed reference
    pFunc = PyDict_GetItemString(pDict, procname);
    if (PyCallable_Check(pFunc))
    {
        pValue = Py_BuildValue("(i)", param);
        PyErr_Print();
        presult = PyObject_CallObject(pFunc, pValue);
        PyErr_Print();
    }
    else
    {
        PyErr_Print();
    }
    //printf("Result is %d\n", _PyLong_AsInt(presult));
    Py_DECREF(pValue);
    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);
    // Finish the Python Interpreter
    Py_Finalize();

    // clean
    delete[] procname;

    return _PyLong_AsInt(presult);
}


void DisplayMenuItems(bool* close) {
    int choice;
    int number;
    int x;

    cout << "1: Display a Multiplication Table" << endl;
    cout << "2: Double a value" << endl;
    cout << "3. Exit program" << endl;
    cout << "Enter your selection as a number 1, 2, or 3." << endl;

    cin >> choice;

    if (choice == 1) {
        cout << "Enter a number: " << endl;
        cin >> number;
        callIntFunc("MultiplicationTable", number);
    }
    else if (choice == 2) {
        cout << "Enter a number: " << endl;
        cin >> x;
        callIntFunc("DoubleValue", x);
    }
    else if (choice == 3) {
        cout << "Exiting program" << endl;
        *close = true;
        return;
    }
    else {
        cout << "You have entered an invalid choice, please try again" << endl;
    }
}


int main()
{
    bool close = false;
    while (!close) {
        DisplayMenuItems(&close);
    }

    return 0;
}

The output is failing to complete the program by displaying the multiplication table and instead displays an interrupted signal as shown below:

Output with segmentation fault error

tristateCS
  • 11
  • 1
  • 1
    *I am having trouble finding the solution to this error in this Multiplication table problem.* [What is a debugger?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – PaulMcKenzie Apr 17 '22 at 01:30
  • In your code there is reference to a 'python_modules.my_module', however that is not included in the example posted here. Perhaps do a `if (pModule)` check right after the call to `pModule = PyImport_Import(pName);` since the subsequent call to `pDict = PyModule_GetDict(pModule);` will result in SIGSEGV if pModule is null. – mvolden Apr 18 '22 at 07:13

0 Answers0